簡體   English   中英

是否可以在C#泛型方法中定義“not Nullable <T>”約束?

[英]Is it possible to define a “not Nullable<T>” constraint in a C# generic method?

在C#中, Nullable<T>類型不滿足where struct泛型約束(而AFAK這在技術上是一個結構)。 這可用於指定泛型參數必須是不可為空的值類型:

T DoSomething<T>() where T : struct
{
   //... 
} 
DoSomething<int?>(); //not ok
DoSomething<int>();  //ok

當然, Nullable<T>也不滿足引用類型where class約束:

T DoSomething<T>() where T : class
{
   //...
} 
DoSomething<int?>(); //not ok
DoSomething<Foo>();  //ok

這是否可以定義約束,例如它必須是引用類型或值類型但不是Nullable值類型?

像這樣的東西:

void DoSomething<T>() where T : class, struct //wont compile!
{    
   //...   
} 
DoSomething<int?>(); //not ok
DoSomething<int>();  //ok
DoSomething<Foo>();  //ok

如評論中所述,您可以使用重載參數(可以是可選的)來執行此操作。 剛剛在博客上寫過這篇文章 ,但在你的情況下,你想要:

public class ClassConstraint<T> where T : class
{
}

public class SomeClass<TViewModel>
{
    public void Add<TValue>(Func<TViewModel, TValue> expression,
                            ClassConstraint<TValue> ignored = null)
        where TValue : class
    {
        AddImpl(expression);
    }

    public void Add<TValue>(Func<TViewModel, TValue> expression,
                            Nullable<TValue> ignored = null)
        where TValue : struct
    {
        AddImpl(expression);
    }

    // No constraints
    private void AddImpl<TValue>(Func<TViewModel, TValue> expression)
    {
        ...
    }
}

這很難看,但它有效:

var z = new SomeClass<string>();
z.Add(x => x.Length);        // Valid (non-nullable value type)
z.Add(x => x);               // Valid (reference type)
z.Add(x => new DateTime?()); // Invalid (nullable value type)

不,在宣言方面是不可能的。 它是struct OR class 但是,您可以在運行時檢查typeof(T)以確保TNullable<T2>

Type type = typeof(T);
if(Nullable.GetUnderlyingType(type) == null)
    throw new Exception();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM