学霸笔记:C#开发工程师之笔记篇2C#开发工程师
今天我们的笔记有两个比较重要的笔记,一个是关于GetHashCode(),另一个是委托,这两个对于我们接下来编程中还是比较重要的,它可以让你能更好的做出你想要的项目。
在引用类型(System.Object)中:GetHashCode()能正常工作,虽然它不必然会产生一个高效的分布。
在值类型(System.ValueType)中:只有在struct的第一个字段是只读的情况下,GetHashCode()才能正常工作,只有当第一个字段包含的值有着相对随机的分布,GetHashCode()才会产生一个比较高效的散列码。
1. 如果两个对象相等(由operator==判断),那么它们必须生成相同散列码。否则,这样的散列码将无法用来查找容器中的对象。System.Object:满足此规则;System.ValueType:并非所有参与等同性判断的属性都会用来进行散列码计算,而是返回struct类型中定义的第一个字段的散列码作为当前值类型的散列码,所以可以认定等同性判断相等的散列码肯定相等(反过来,散列码相等同性判断不一定相等)。满足此规则。
2. 对于任何一个对象A,A.GetHashCode()必须保持不变。不管在A上调用什么方法,A.GetHashCode()都必然总是返回同一个值。这样可以确保放在“桶”中的对象总是位于正确的“桶”中。System.Object:满足此规则;System.ValueType:struct中的第一个字段是一个常量字段,不会在生存期发生改变(称为不可变的值类型),满足此规则。、
3. 对于所有的输入,散列函数应该在所有整数中按照随机分布生成散列码。这样,散列容器才能得到足够的效率提升。System.Object:系统每创建一个对象时会指派一个唯一的对象键(一个整数值),从1开始,每创建一个任意类型的新对象,键值会随之增长,虽然System.Object.GetHashCode()能正常工作,但因为不是随机分布,效率不高,所以没有满足此规则,新建引用类型时建议覆写GetHashCode();System.ValueType:依赖于第一个字段的使用方式,如果取任意值,GetHashCode()可以产生比较均匀的分布,但如果取相同的值则没有此满足规则。
内建的委托形式
· Predicate<T>:表示一个提供布尔型返回值的函数;
· Action<T1,T2>:接受任意参数目的参数;
· Func<T1,T2,ResultT>:接受零到多个参数,并返回单一结果;
.NET的委托都是多播委托(multicast delegate),多播委托将会把所有添加到该委托中的所有目标函数组合成一个单一的调用。有两点需要注意:
1. 在多播委托调用过程中,每个目标函数会被依次调用。委托对象本身不会捕获异常。因此,任何目标抛出的异常都会结束委托链的调用,如果有委托调用出现异常,那么这种方式不能保证安全;
2. 整个调用的返回值将为最后一个函数调用的返回值,前面函数的返回值将会被忽略;
解决方法:自己遍历调用列表,调用委托链上的每个目标函数
接受Predicate<>、Action<>、Func<>为参数的方法,如List<T>.Find(Predicate<T> p);有时传入lambda表达式,编译器会把lambda表达式转换成方法,然后创建一个委托,指向该方法,然后调用委托实现回调。
.NET的事件模式就是观察者模式
public event EventHandler<LoggerEventArgs> Log;
编译器会自动创建类似下面的代码,根据需要可以自己编写
private EventHander<LoggerEventArgs> log;
public event EventHander<LoggerEventArgs> Log
{
add{log=log+value;}
remove{log=log-value;}
}
事件相当于一个委托集合,可以添加多个同类型委托(通过+=);
委托可以添加多个同类型方法(通过构造函数或+=);
我觉得今天我学习的笔记中这两个比较重要,希望能帮到大家,大家可以关注汇鱼网,汇鱼网每天都会更新资讯,上面可能会有你想要的答案。


1914篇文章