【问题标题】:Is there a way to define an generic interface with a constraint that the type can be null (but cannot be a value type)?有没有办法用类型可以为空(但不能是值类型)的约束来定义通用接口?
【发布时间】:2015-12-16 18:30:02
【问题描述】:

我想定义一个通用接口,它允许可以为 null 的值类型(int?、double? 等)和类类型(也可以为 null)。我不想允许一个简单的值类型。有没有办法做到这一点?

【问题讨论】:

    标签: c# .net generics nullable


    【解决方案1】:

    编辑:给定问题标题,我假设您希望将类型参数限制为 not 是不可为空的值类型。在问题 body 中也指定这一点可能是个好主意。

    不 - 没有这样的限制。事实上,class 和 struct 约束都禁止可空值类型的参数。

    你可以创建一个没有约束的接口,但只能创建两个实现:

    interface IFoo<T> { }
    
    class FooClass<T> : IFoo<T> where T : class {}
    
    class FooNullableValue<T> : IFoo<Nullable<T>> where T : struct {}
    

    当然,这不会阻止其他任何人实施IFoo&lt;int&gt;。如果您能提供更多背景信息,我们或许可以提供更多帮助。

    【讨论】:

    • 这两个实现正是我们目前正在做的。我只是不相信两者都需要。我相信你已经确认了这个需求。
    【解决方案2】:

    是的,只要不使用约束就可以指定任何类型:

    public interface IAllowReferenceTypes<T>
    {
       T GetValue();
    }
    
    public class SomeClass : IAllowReferenceTypes<Int32?>
    {
       public Int32? GetValue() { return null; }
    }
    

    编辑:已修复。

    注意:您在标题中要求一个约束,但在正文中,如果您的问题只是要求一个允许可为空值类型和引用类型的接口。

    不使用约束可以完成后者。正如乔恩的回答所指出的那样,没有办法使用约束来保证类型可以为空。但是,您可以不使用任何约束并检查 null(或 default(T))

    【讨论】:

    • 这不允许为空值类型,这是问题所要求的。
    • Sonofa。喝咖啡前不要回答 SO。
    • 丹尼尔,从来没有说过更聪明的话。
    • @DanielSchaffer:这现在允许不可为空的值类型,这与问题的标题背道而驰,假设我已经正确解释了它。
    • @Jon 我想问题的标题和正文提出的问题略有不同。
    【解决方案3】:

    This 可能就是您要找的。​​p>

    格雷格·迪恩的回答:


    将返回类型改为Nullable,并调用带有不可为空参数的方法

    static void Main(string[] args)
    {
        int? i = GetValueOrNull<int>(null, string.Empty);
    }
    
    
    public static Nullable<T> GetValueOrNull<T>(DbDataRecord reader, string columnName) where T : struct
    {
        object columnValue = reader[columnName];
    
        if (!(columnValue is DBNull))
            return (T)columnValue;
    
        return null;
    }
    

    另外,请参阅以下有关通用接口的 MSDN 文章:http://msdn.microsoft.com/en-us/library/kwtft8ak.aspx

    【讨论】:

    • 请不要发布指向特定版本的 MSDN 文章的链接,除非问题是特定于版本的。
    • @JohnSaunders - 抱歉,没有意识到我有。刚刚看到相关性并发布了它。
    • 仅供参考,这就是为什么不发布旧链接的原因。读者陷入了旧链接的迷宫,甚至没有意识到他们正在阅读旧信息。
    • 是的,我什至没有注意到我已经做到了,直到你指出来。它与现在相关(VS2010)但它不是面向未来的。
    • @Polynomial 一个词,“帽子”。除了您的答案在评论阙中的低质量答案之外,有人标记了它。
    猜你喜欢
    • 1970-01-01
    • 2017-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多