了解C#泛型和Nullable值类型。返回null或可空

时间:2012-10-30 16:27:50

标签: c# generics mono null nullable

假设我有以下课程:

public class GenericClass<T>
{
    public T Find()
    {
        //return T if found otherwise null or Nullable<T>
    }
}

某个地方我想使用T class使用struct专注我的班级,其他时间使用Nullable<T>。 我正面临这个issue:如果T类型不限于struct,我就无法返回Find

我想提供T方法的实现,如果class专门用于structFind,则该方法有效。 在null失败的情况下,如果T是一个类别Nullable<T>,我想返回{{1}}。

这可能不使用反射吗?如果是的话怎么样?

3 个答案:

答案 0 :(得分:16)

您可以返回default(T)

对于课程,这将是null。对于任何Nullable<T>,这将是Nullable<T>没有值(有效null)。

话虽如此,如果您使用struct而不是Nullable<T>作为类型,default(T)将是结构的默认值。


如果你想为任何类或结构统一工作,你可能需要返回两个值 - 你可以在这里使用框架作为灵感,并使用TryXXX方法,即:

public bool TryFind(out T)

然后,您可以在找不到值时使用default(T),并返回false。这避免了对可空类型的需求。你也可以写这个返回Tuple<bool, T>或类似的,如果你想避免out参数,即:

public Tuple<bool, T> Find()

最后一个选项可能是让你的类非泛型,然后使用一对泛型方法:

class YourClass // Non generic
{
    public T FindReference<T>() where T : class
    {
         // ...
        return null;
    }

    public Nullable<T> FindValue<T>() where T : struct
    {
         // ...
         return default(T);
    }
}

请注意,您需要不同的名称,因为您不能完全基于返回类型重载方法。

答案 1 :(得分:2)

我会使用以下解决方案:

public Boolean Find(out T result)
{
    // Pseudo code
    if (FindItem == true)
    {
        result = ItemFound;
        return true;
    }
    result = default(T);
    return false;
}

为什么呢?因为Nullable<T>只接受一个结构,并且上面的方法支持类,结构和结构。

答案 2 :(得分:0)

正如里德所说,你可以回归default(T)

在我看来,这有一个很大的缺点:如果您的方法声明如果找不到项目则返回default(T),则您将无法返回值类型的默认值(例如,返回{{1} } 0通常可能是完全有效的返回值。)

我宁愿选择这样的东西

Find<int>