C#泛型約束(where T : class)


.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
{ }
struct
public class MyGenericClass<T> where T : IComparable, new()
{
    // The following line is not possible without new() constraint:
    T item = new T();
}
new
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;
}
泛型委托

泛型委托


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM