【问题标题】:Using is operator with Interface to Generics使用带有泛型接口的 is 运算符
【发布时间】:2010-12-19 13:51:54
【问题描述】:

我有一些实现通用非泛型接口的泛型类。我创建了我的通用对象并将它们添加到列表中。我如何使用 LINQ 或任何其他方法来按泛型类型过滤列表。我不需要在运行时知道 T 。我在接口中添加了一个类型属性并使用 LINQ 对其进行过滤,但我希望使用 is 运算符。这是我拼凑的一个简单示例。

有什么想法吗?

interface IOperation
    {
        object GetValue();
    }
    class Add<T> : IOperation
    {
        public object GetValue()
        {
            return 0.0;
        }
    }
    class Multiply<T> : IOperation
    {
        public object GetValue()
        {
            return 0.0;
        }
    }


    private void Form1_Load(object sender, EventArgs e)
    {
        //create some generics referenced by interface
        var operations = new List<IOperation>
        {
            new Add<int>(),
            new Add<double>(),
            new Multiply<int>()
        };

        //how do I use LINQ to find all intances off Add<T> 
        //without specifying T?

        var adds =
            from IOperation op in operations
            where op is Add<> //this line does not compile
            select op;
    }

【问题讨论】:

    标签: c# generics operators interface


    【解决方案1】:

    您可以只比较底层的非参数化类型名称:

    var adds =
        from IOperation op in operations
        where op.GetType().Name == typeof(Add<>).Name
        select op;
    

    请注意,在 C# 的下一版本中,由于差异,这将是可能的:

    var adds =
        from IOperation op in operations
        where op is Add<object>
        select op;
    

    【讨论】:

    • 请记住,C# 4 中的协变和逆变只适用于泛型接口和委托,不适用于类和结构,并且类型参数必须是引用类型。在本例中是否满足所有这些条件?
    • 不上课?我可以很好地使用ReadonlyList&lt;int&gt;ReadonlyList&lt;object&gt;,不是吗?
    • 糟糕,关于方差,你是对的。我们需要你的接口。
    • 绝对不能将 ReadOnlyList 用作 ReadOnlyList。类类型没有协方差,并且方差要求两个类型参数都是引用类型。不允许这样做的原因很简单:假设它被允许并推断出矛盾。 ReadOnlyList 的索引器将一个未装箱的整数放入堆栈。具有 ReadOnlyList 引用的调用者期望调用索引器以将对象引用放入堆栈。未装箱的整数不是对象引用,因此我们破坏了类型安全性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    • 2020-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多