C#学习笔记(八)C#的一些设计技巧

编码习惯

1.命名规范,接口用I开头做前缀,异常类使用Exception作为后缀。内部成员变量用Camel命名法。小写开关,每单词首字母大写。
2.使用有意义的变量名称和名称空间。有返回值的方法形如GetMyObjectState()。
3.所有的成员变量都应该声明在顶部,同时使用一个空行来将它们和属性
、方法分开。
4.总是将大括号放在一个新行上。


委托再议

定义委托实际上是定义一个“类型”的委托,不是一个具体的实例。委托类型指定它代表的方法的返回类型和参数列表。它代表具有相同参数列表和返回类型的任何方法。

<modifiers>delegate <return_type><delegate_name>(argument_list)
-->
public delegate bool ProcessAnything(double d);

创建委托实例,new关键字。
ProcessAnything pa = new ProcessAnything(account.WithDraw);
括号里面是实例方法,此方法必须和代理声明时的返回类型和参数列表相同。

委托的调用时通过输入委托实例的名称和要传递给委托所表示的方法的参数。

 

Equals

考虑覆写Equals(object obj)。.NET提供了默认的实现方法(引用指向同一对象),.NET将在比较和查询时使用这个方法,实现自己比较的“相等”定义,就需要覆写此方法。
例如,两个客户名称或代码相同,我们就认为对象是相同的。对.NET来说,如果new了两次就认为是不同的。这里需要覆写。如:


public class BankCustomer
{

    public string FirstName;
    public string LastName;
    //……


public override bool Equals(object obj)
{
    if (obj==null)
        return false;
    if ((obj.GetType().Equals(this.GetType())) == false)
        return false;
    BankCustomer other;
    other = (BankCustomer)obj;
    return this.FirstName.Equals(other.FirstName) && this.LastName.Equals(other.LastName);


}

}


要求:
Equals必须是自反的(自己比较自己必须返回True)。必须是对称的(X Equals Y则 Y Equals X)。必须是可以传递的,(即X Equals Y ,Y Equals Z,则X Equals Z。)必须是一致的,如果被比较的值没有变化,则始终应返回同一结果。

如果覆写了Equals,也需要覆写GetHashCode。(不覆写的情况下编译器会提出警告)。这是因为如果两个对象Equals,GHC必须返回相同的值。可根据Equals字段来覆写GHC。

public override int GetHashCode()
{
    return this.FirstName.GetHashCode() + this.LastName.GetHashCode();

}

HashTable提供高效的搜索,基于(Key,Value)pairs(键/值)对-键必须是唯一的,可通过搜索Key来查找。

 


Clone

如果要实现克隆功能,就要实现ICloneable接口。实现clone方法。
需要确定是“浅表复制”还是“深复制”。浅复制(shallow)复制顶级对象;深复制(deep)是复制对象和子对象。

return new BankCustomer(...);相当于
return this.MemberwiseClone();

Close & Dispose

实现IDisposable。一些对象需要清理。如果类中“抓住”资源,应该重新设计类,实现Dispose & Close方法。

 

XML文档索引

使用XML注释,自动完成class-level文档。例如:

///<summary>
///说明……
///</summary>
///<param name = "amt"> 参数说明</param>
///<exception cref = "System.Exception"> 异常抛出说明</exception>


String相关知识

string是不可变的对象。字符串操作并不更改当前字符串,而是创建并返回新的字符串,速度慢。

要频繁进行字符串连接操作时,可使用StringBuilder类来发送性能。连接操作越频繁,差别越明显。

字符串驻留
如果生成新的字符串时会查找系统内在中是否有相应的字符串,如果找到就指向该内在。节省内存空间。使用Intern关键字(可查找相关资料)。

 

委托的概念及定义

用特定的签名(即返回值类型和参数列表)来封装方法。一个委托的实例可以用来封装一个静态或实例的方法。是类型安全的。

(MSDN Microsoft)

委托是一个回调功能,但更智能,它定义了非常严格的参数,使之可以在类的服务端和客户端传递。
(CodeProject)

委托是一种引用方法的类型,一旦分配了方法,将与该方法具有完全相同的行为。委托方法的使用可以像其它任何方法一样具有参数和返回值。
(C#编程指南)

增加一层间接层来实现晚绑定,从而获得更为松散的耦合。


一个委托可以一次搭载多个方法,而不是一次一个。当我们唤起一个搭载了多个方法的委托时,所有方法以其被搭载到delegate object的顺序被依次唤起。

实际上是创建了Delegate类或MulticastDelegate类,提供一组方法用以询访委托对象或其搭载的方法。


委托是函数的封装,代表一“类”函数,符合一定的签名。同时,也可以看成函数的抽象,是函数的“类”,此时,委托的实例代表一个具体的函数。

 

 

为什么使用委托

1)更加灵活的方法调用。
2)用于异步回调

    由于实例化委托是一个对象,所以可将其作为参数进行传递,也可以将其赋值给属性。这样方法便可以将一个委托作为参数来接受,并且以后可以调用该委托。这称为异步回调,是在较长的进程完成后用来通知调用方的常用方法。以这种方式使用委托时,使用委托的代码无需了解有关所有方法的实现方面的任何信息。
如:

public void MethodWithCallback(int parm1,int parm2, Del callback)

{
    callback("The Number is:" +
    (parm1+parm2).ToString());
}

回调的另一个常见方法是定义自定义的比较方法并将该委托传递给排序方法。

 

3)多线程编程中使用委托来指定启动一个线程时调用的方法。
4)用于C#中的事件模型。用它们指明处理给定事件的方法。

 

如何使用委托

先声明,再实例化并指明所代具体方法。

何时委托,何时接口?
使用委托建议
1)使用事件设计模式时
2)封装静态方法可取时
3)当调用方不需要访问实现该方法的对象中其他属性、方法或接口时
4)需要方便的组合
5)当类可能需要该方法的多个实现时。
使用接口建议
1)当存在一组可能被调用的相关方法时。
2)当类只需要方法的单个实现时。
3)当使用接口的类想要将该接口强制转换为其他接口或类类型时。

 

多播委托应用于事件模型。

代理相加。Button.Click+=...

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值