【问题标题】:Covariance issue with interfaces causes back and forth casting接口的协方差问题导致来回转换
【发布时间】:2013-08-31 22:21:24
【问题描述】:

我正在为我正在处理的项目使用 .NET 3.5。我遇到了一个小而烦人的协方差问题。这与我目前的模式相似:

public interface ISupportSomething<T> where T : struct
{
    T StructProperty { get; set; }
}

public class SupportSomething : ISupportSomething<int>
{
    public int StructProperty { get; set; }
}

public static class ISupportSomethingExtensions
{
    public static IEnumerable<ISupportSomething<T>> Method<T>
            (this IEnumerable<ISupportSomething<T>> collection)
    {
        return null;
    }
}

public class SupportTester
{
    private void SomeMethod()
    {
        IEnumerable<SupportSomething> source;

        // invalid, i would generally fix this with a covariant
        // declaration: ISupportSomething<out T>
        var methodResult1 = source.Method();

        // valid
        var methodResult2 = source.Cast<ISupportSomething<int>>().Method();

        // this means that if i want to make a function that
        // returns an IEnumerable<SupportSomething> that
        // has called ISupportSomethingExtensions.Method i
        // have to do this cast back and forth approach

    }

    // here is a similar function to what i have that showcases the ugliness
    // of calling this extension method
    private IEnumerable<SupportSomething> SomeFunction()
    {
        IEnumerable<SupportSomething> source;

        var tempSourceList = source.Cast<ISupportSomething<int>>();

        tempSourceList = tempSourceList.Method();

        return tempSourceList; // invalid
        return tempSourceList.Cast<SupportSomething>(); //valid
    }
}

我的问题很简单,我想我已经知道答案了,但是:在 .NET 3.5 中,有没有办法在处理这些对象时不必来回转换(参见最后一个函数)?

我猜我运气不好,不得不这样做,因为在 .NET 4.0 之前没有对协方差的通用支持。

【问题讨论】:

    标签: c# .net-3.5 covariance


    【解决方案1】:

    你可以像这样修改扩展方法:

    public static class ISupportSomethingExtensions
    {
        public static IEnumerable<T1> Method<T1, T2>
                (this IEnumerable<T1> collection)
            where T1 : ISupportSomething<T2>
            where T2 : struct
        {
            return null;
        }
    }
    

    现在它不需要依赖 IEnumerable 的协变来工作。

    此更改的不幸站点影响是 Method 将不再能够推断出它的通用参数,您需要明确列出:

    private IEnumerable<SupportSomething> SomeFunction()
    {
        IEnumerable<SupportSomething> source = Enumerable.Empty<SupportSomething>();
    
        return source.Method<SupportSomething, int>();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-22
      • 1970-01-01
      • 2013-01-23
      • 1970-01-01
      • 1970-01-01
      • 2017-05-15
      • 1970-01-01
      相关资源
      最近更新 更多