关于C#generics的最重要的事情……经验教训

您对generics有哪些最重要的知识:隐藏的function,常见错误,最佳和最有用的实践,提示……

我开始使用generics实现我的大部分库/ API,并希望收集在实践中发现的最常见的模式,提示等。

让我说一下这个问题:你对仿制药学到的最重要的事情是什么?

请尝试提供示例 – 与易于理解和过于干燥的描述相比,它更容易理解

谢谢

这个问题有点类似于Jon的问题 ,但是在另一个主题上。

我学到的最重要的事情之一是你可以约束generics类型参数 。 这可能非常强大,允许您仅为特定类型的对象定制类,并允许您在generics类中使用该类型的成员。 我意识到这是非常基础的,但它是让generics非常有用的东西之一。

当涉及到静态成员之类的东西时,generics类型的每个特化都被视为唯一类型。 例如,使用此类型:

class GenericType { public static int SomeValue; } 

如果我们这样做,断言成功:

 GenericType.SomeValue = 3; Debug.Assert(GenericType.SomeValue == 0); 

这是因为:

 typeof(GenericType) != typeof(GenericType) 

即使

 typeof(GenericType.GetGenericTypeDefinition() == typeof(GenericType).GetGenericTypeDefinition() 

理解C#中generics类型推断的function和局限性。 基于(例如)方法中的参数类型,可以深入理解编译器可以和不能推断的内容,以使API的常见用例更具可读性。

我学到的关于generics的最重要的教训是:你使用它们越多越好。

没有协方差或反方差 (至少在3.5中)。 在设计包含generics类型参数的类层次结构时要注意这一点。

两个有趣的课程。 第一; 列表; 试着用T来思考; 有关详细信息,请参阅此处 ,但简而言之,您需要使用:

 public void Foo(IList data) where T : SomeBaseClassOrInterface {} 

并不是:

 public void Foo(IList data) {} 

第二: 注意边缘情况 ;-p

你能在这看到陷阱吗?

 static void Foo() where T : new() { T t = new T(); Console.WriteLine(t.ToString()); // works fine Console.WriteLine(t.GetHashCode()); // works fine Console.WriteLine(t.Equals(t)); // works fine // so it looks like an object and smells like an object... // but this throws a NullReferenceException... Console.WriteLine(t.GetType()); // BOOM!!! } 

不知道它们是否最重要,但我学会了以下内容:

如果你不知道frikkin类型,generics只能通过reflection实例化。 在某些情况下,您可能需要非generics接口才能在类型未知的情况下使用generics类。

我几乎弄坏了我的头,直到我厌倦了

 public class Foo where T : Foo { public T CloneMe() ... } 

是完全有效的代码,并允许您的基类公开与专用类相关的方法和属性…最终在状态机的状态定义:

 public abstract class Machine where S : State where M : Machine { protected S state; } public abstract class State where S : State where M : Machine { protected M machine; } 

generics可能会有点笨拙。 前几天我有这个:

 List>,Expression>>> 

呼…

 MyGeneric where T : IComparable 

没有

 MyGeneric 

它的基类。

我已经了解到generics是非常强大的工具但滥用会导致代码难以理解。

通用委托类型始终是类型不变的。

我遇到了类似于前几天链接中概述的问题,这引起了一些混乱,因为我不明白为什么我必须投出我的collections。

http://www.theserverside.net/blogs/thread.tss?thread_id=47323

首先,了解generics如何在C#中工作是非常重要的。 本文为Anders Hejlsberg(c#之父)提供了一个很好的generics概述。 我不认为尽可能经常使用它们就是那么好。 在真正有意义的时候使用generics。 永远记住极限编程中的KISS和YAGNI(保持简单愚蠢;你不需要它)。