1、The CLR doesn’t allow overloading based on type parameter names or constraints; you can overload types or methods based only on arity.
2、Whenoverriding a virtual generic method, the overriding method must specify the same num-ber of type parameters, and these type parameters will inherit the constraints specified on them by the base class’s method. In fact, the overriding method is not allowed to specify any constraints on its type parameters at all.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyGenerics4 { internal class Base { public virtual void M<T1, T2>() where T1 : struct where T2 : class { } } internal sealed class Derived : Base { public override void M<T3, T4>() where T3 : EventArgs // Error where T4 : class // Error { } } class Program { private static bool MethodTakingAnyType<T>(T o) { T tmp = o; Console.WriteLine(o.ToString()); bool b = tmp.Equals(o); return b; } public static T Min<T>(T o1, T o2) where T : IComparable<T> { if (o1.CompareTo(o2) < 0) return o1; return o2; } private static void CallMin() { Object o1 = "Jeff", o2 = "Richter"; Object oMin = Min<Object>(o1, o2); // Error CS0311 } // It is OK to define the following types: internal sealed class AType { } internal sealed class AType<T> { } internal sealed class AType<T1, T2> { } // Error: conflicts with AType<T> that has no constraints internal sealed class AType<T> where T : IComparable<T> { } // Error: conflicts with AType<T1, T2> internal sealed class AType<T3, T4> { } internal sealed class AnotherType { // It is OK to define the following methods: private static void M() { } private static void M<T>() { } private static void M<T1, T2>() { } // Error: conflicts with M<T> that has no constraints private static void M<T>() where T : IComparable<T> { } // Error: conflicts with M<T1, T2> private static void M<T3, T4>() { } } static void Main(string[] args) { } } }1、首要约束(Primary Constraints)
2)The struct constraint promises the compiler that a specified type argument will be a value type. Any value type, including enumerations, satisfies this constraint.
internal sealed class PrimaryConstraintOfClass<T> where T : class { public void M() { T temp = null;// Allowed because T must be a reference type } } internal sealed class PrimaryConstraintOfStruct<T> where T : struct { public static T Factory() { // Allowed because all value types implicitly // have a public, parameterless constructor return new T(); } }
2、次要约束(Secondary Constraints)
1)接口类型约束
<pre name="code" class="csharp"> private static List<TBase> ConvertIList<T, TBase>(IList<T> list) where T : TBase { List<TBase> baseList = new List<TBase>(list.Count); for (Int32 index = 0; index < list.Count; index++) { baseList.Add(list[index]); } return baseList; } private static void CallingConvertIList() { // Construct and initialize a List<String> (which implements IList<String>) IList<String> ls = new List<String>(); ls.Add("A String"); // Convert the IList<String> to an IList<Object> IList<Object> lo = ConvertIList<String, Object>(ls); // Convert the IList<String> to an IList<IComparable> IList<IComparable> lc = ConvertIList<String, IComparable>(ls); // Convert the IList<String> to an IList<IComparable<String>> IList<IComparable<String>> lcs = ConvertIList<String, IComparable<String>>(ls); // Convert the IList<String> to an IList<String> IList<String> ls2 = ConvertIList<String, String>(ls); // Convert the IList<String> to an IList<Exception> IList<Exception> le = ConvertIList<String, Exception>(ls);// Error }3、构造器约束(Constructor Constraints)
internal sealed class ConstructorConstraint<T> where T : new() { public static T Factory() { // Allowed because all value types implicitly // have a public, parameterless constructor and because // the constraint requires that any specified reference // type also have a public, parameterless constructor return new T(); } }