4

在 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
4

2 回答 2

3

如评论中所述,您可以使用重载参数(可以是可选的)来执行此操作。前段时间我在博客上写过这个,但在你的情况下,你会想要:

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)
于 2015-02-11T11:33:01.227 回答
2

不,在声明方面是不可能的。它是structOR class。但是,您可以在运行时检查以typeof(T)确保TNullable<T2>

Type type = typeof(T);
if(Nullable.GetUnderlyingType(type) == null)
    throw new Exception();
于 2015-02-11T11:15:44.587 回答