.NET支持的類型參數約束有以下五種:
where T : struct | T必須是一個結構類型
where T : class | T必須是一個Class類型
where T : new() | T必須要有一個無參構造函數
where T : NameOfBaseClass | T必須繼承名為NameOfBaseClass的類
where T : NameOfInterface | T必須實現名為NameOfInterface的接口
到這里我們看出,泛型約束是不支持枚舉的,為什么呢?
因為enum是值類型,而所有的值類型都是sealed,所以都不能進行約束。但是,若要限制參數為值類型,可用struct 約束。
很可惜泛型不支持枚舉型,不過我們可以通過以下方法判斷是否枚舉: if (!typeof(T).IsEnum)

/// <summary> /// 獲取枚舉值上的Display特性的說明 /// <para>用法: string name = WeekEnum.Sunday.Display();</para> /// <para>結果: name = "星期天";</para> /// </summary> /// <typeparam name="T">枚舉</typeparam> /// <param name="obj">枚舉</param> /// <returns></returns> public static string Display<T>(this T obj) { try { if (!typeof(T).IsEnum) { return string.Empty; } var type = obj.GetType(); FieldInfo field = type.GetField(System.Enum.GetName(type, obj)); DisplayAttribute descAttr = Attribute.GetCustomAttribute(field, typeof(DisplayAttribute)) as DisplayAttribute; if (descAttr == null) { return string.Empty; } return descAttr.GetName(); } catch { return string.Empty; } }

public static T GetParent<T>(UIElement uiElement) where T : class { T result; var dp = LogicalTreeHelper.GetParent(uiElement); result = dp as T; while (result == null) { dp = LogicalTreeHelper.GetParent(dp); result = dp as T; if (dp == null) return null; } return result; }

class MyClass<T, U> where T : class where U : struct { }

public class MyGenericClass<T> where T : IComparable, new() { // The following line is not possible without new() constraint: T item = new T(); }

interface IMyInterface { } class Dictionary<TKey, TVal> where TKey : IComparable, IEnumerable where TVal : IMyInterface { public void Add(TKey key, TVal val) { } }

delegate T MyDelegate<T>() where T : new() { }

public delegate void Del<T>(T item); public static void Notify(int i) { } Del<int> m1 = new Del<int>(Notify); delegate void StackEventHandler<T, U>(T sender, U eventArgs); class Stack<T> { public class StackEventArgs : System.EventArgs { } public event StackEventHandler<Stack<T>, StackEventArgs> stackEvent; protected virtual void OnStackChanged(StackEventArgs a) { stackEvent(this, a); } } class SampleClass { public void HandleStackChange<T>(Stack<T> stack, Stack<T>.StackEventArgs args) { } } public static void Test() { Stack<double> s = new Stack<double>(); SampleClass o = new SampleClass(); s.stackEvent += o.HandleStackChange; }