1. c# 是怎么支持泛型的?
泛型 = 编译器支持+JIT支持
控制台 编译生成 exe或dll, 然后 exe被点击时, 由 JIT(即时编译器 Just-In-Time) 即时编译变成机器码
编译器针会把 泛型 编译成占位符, JIT 编译时, 会把它替换为真实类型
2. 泛型方法的效率怎么样?
generic≈原生代码>obj(装箱拆箱)
public class Monitor
{
public static void Show()
{
Stopwatch watch = new Stopwatch();
watch.Start();for (int i = 0; i < 100000000; i++)
{
ShowInt(i);
}
watch.Stop();
Console.WriteLine("ShowInt: {0}",watch.ElapsedMilliseconds);watch.Restart();
for (int i = 0; i < 100000000; i++)
{
ShowObj(i);
}
Console.WriteLine("ShowObj: {0}", watch.ElapsedMilliseconds);watch.Restart();
for (int i = 0; i < 100000000; i++)
{
ShowGeneric<int>(i);
}
Console.WriteLine("ShowGeneric: {0}", watch.ElapsedMilliseconds);
watch.Stop();}
public static void ShowInt(int param){
//do nothing
}public static void ShowGeneric<T>(T param)
{
//do nothing
}public static void ShowObj(object param)
{
//do nothing
}
}
3. 逆变与协变 参考链接http://www.cnblogs.com/yukaizhao/archive/2011/10/27/xiebian-nibian.html
一句话: 如果一个方法要接受Dog参数,那么另一个接受Animal参数的方法肯定也可以接受这个方法的参数,这是Animal向Dog方向的转变是逆变。
如果一个方法要求的返回值是Animal,那么返回Dog的方法肯定是可以满足其返回值要求的,这是Dog向Animal方向的转变是协变。
class Program
{
static void Main(string[] args)
{
//协变 如果一个方法要求的返回值是Animal,那么返回Dog的方法肯定是可以满足其返回值要求的,这是Dog向Animal方向的转变是协变
ICustomerListOut<Person> customerListOut1 = new CustomerListOut<Person>();
ICustomerListOut<Person> customerListOut2 = new CustomerListOut<Man>();//逆变 如果一个方法要接受Dog参数,那么另一个接受Animal参数的方法肯定也可以接受这个方法的参数,这是Animal向Dog方向的转变是逆变
ICustomerListIn<Person> customerListIn1 = new CustomerListIn<Person>();
ICustomerListIn<Man> customerListIn2 = new CustomerListIn<Person>();}
}/// <summary>
/// out 协变 只能作为返回类型
/// </summary>
/// <typeparam name="T"></typeparam>
public interface ICustomerListOut<out T>
{
T Get();
//void Show(T t); //T不能作为传入参数
}/// <summary>
/// 类 没有协变/逆变的概念, 只有接口/委托支持协变
/// </summary>
/// <typeparam name="T"></typeparam>
public class CustomerListOut<T> : ICustomerListOut<T>
{
public T Get()
{
return default(T);
}
}/// <summary>
/// 逆变 in 只能作为传入类型
/// </summary>
/// <typeparam name="T"></typeparam>
public interface ICustomerListIn<in T>
{
//T Get();//T不能作为返回参数
void Show(T t);
}public class CustomerListIn<T> : ICustomerListIn<T>
{
public void Show(T t)
{
throw new NotImplementedException();
}
}
public class Person
{
public int Id { get; set; }
}public class Man : Person
{
public string Name { get; set; }
}