目标哈希码

GetHashCode虚办法
System.Object供给了GetHashCode虚办法,能够获得恣意目标的Int32哈希码;

GetHashCode与自定义类型的重写

  • 内容
    • 此GetHashCode虚办法能够在子类中被进行重写,而且假如自定义类型重写了Equals,则此GetHashCode建议一定要重写。
  • 原因
    • 由于在一些数据结构,比方字典或许哈希表傍边,其内部算法完成时是基于目标类型的Equals来检测两个目标是否持平,而假如重写了Equals,则还需求其对应的GetHashCode办法来保证两个目标不仅在每个字段上持平,还保证其在哈希码上也持平。
    • 基于引证类型的变量需求

自定义GetHashCode
参阅完成:

internal sealed class Point
{
	private readonly Int32 m_x,m_y;
	public override Int32 GetHashCode()
	{
		return m_x ^ m_y;
	}
}

自定义计算哈希码注意规则

  • 1、算法供给良好的随机分布
  • 2、可在算法中调用基类的GetHaseCode,可是不要调用Object或许ValueType傍边的GetHashCode办法,由于这两者由于内容过于笼统,完成成果和高性能哈希算法不沾边;
  • 3、算法至少运用一个实例字段,而且此实例字段应该为不可变;
  • 4、包含相同值的不同目标应该返回相同的哈希码;

dynamic基元类型

类型安全的意义
意义:

  • C#是类型安全的语言,这意味着一切代码中呈现的表达式,都会被解析成类型的实例,编译器生成的代码只执行对该类型有效的操作。
    类型安全的优势:
  • 程序员犯得许多过错都能够在编译时检测到,保证代码在测验执行前是正确的;
  • 由于会在编译时做出更多的预设,能够编译出更小、更快的代码;
    不足:
  • 程序有时仍然需求处理一些运行时才会知晓的信息,尤其是在和一些不运用C#完成的组件之间进行通信时,有时经常会需求开发人员和其他组件进行通信;

dynamic关键字
呈现原因:

  • 为了方便开发人员运用反射或许和其他组件之间进行通信,C#编译器允许将表达式的类型或许成果变量标记为dynamic,进而用dynamic来调用成员。
    Payload:
  • 代码运用dynamic时,编译器会生成特殊的IL代码来描述所需操作,这些特殊的代码被称为payload,在运行时payload代码依据dynamic表达式或许变量引证的目标的实践类型来决议详细执行的操作;

dynamic执行时行为

代码演示

internal class Program
	{
		static void Main(string[] args)
		{
			dynamic value;
			for (int i = 0; i < 2; i  )  
			{
				value = (i == 0) ? (dynamic)5 : (dynamic)"A";
				value = value   value;
				M(value);
			}
		}
		private static void M(Int32 n) 
		{
			Console.WriteLine("M(Int32)"   n.ToString());
		}
		private static void M(string s)
		{
			Console.WriteLine("M(String)"   s);
		}
	}

概念:

  • 核心:编译器会将dynamic转化成Object,而且添加DynamicAttribute实例;
  • 当两个操作数的类型时dynamic时,C#编译器会生成payload代码在运行时检查value的实践类型;
  • 假如字段、办法参数或许办法返回值的类型是dynamic,编译器会将该类型转化为System.Object,并在元数据中向字段、参数、返回值类型变量运用System.Runtime.CompilerSerivces.DynamicAttribute的实例,局部变量不会运用此,但也会成为Object;

dynamic类型转化

dynamic转型
概念:

  1. 一切表达式都能隐式的转化为dynamic,由于一切表达式都最终生成从Object继承的类型;
  2. 将代码表达式从Object转型成其他类型需求显示转型,但编译器允许运用隐式转型将dynamic转型为其他类型。假如目标类型不兼容,CLR会抛出InvalidCastException反常;
    演示:
dynamic n1 = 32;//OK
Int32 n2 = n1;//OK

dynamic与var
var:

  • var要求编译器依据表达式推断详细数据类型,只能在办法内部声明局部变量;
    dynamic:
  • dynamic能够运用在局部变量、字段以及参数傍边;
  • 表达式不能转型为var,但能转型为dynamic;

dynamic与反射
运用分析:

  • 优点:
    • 运用C#的dynamic能够明显简化语法;
  • 缺点:
    • payload代码执行时,会在程序运行时生成动态代码,这些代码进入住留存于内存的程序集,加载这些程序集会产生额外的内存耗费。
  • 运用:
    • 假如程序仅仅一、两个当地需求动态行为,运用传统的反射办法愈加高效;

演示:

dynamic target = "Mike";
dynamic arg = "ff";
Boolean result = target.Contains(arg);

Contains是String类傍边的办法,经过dynamic在运行时得到其类型信息,直接运用办法;