繁体   English   中英

为什么我不能从受约束的泛型集合中推断出接口?

[英]Why can I not infer an interface from a constrained generic collection?

我有一段代码如下:

public IEnumerable<ICacheMember> Flubvert( IEnumerable<ICacheMember> members ) 
   {
        // do some stuff to members
        return members;
   }

但是我很困惑为什么我不能这样做:

public IEnumerable<T> ExecuteFlubversion<T>( IEnumerable<T> memberList ) where T: class,ICacheMember 
{
      return Flubvert( memberList );
}

当然,对泛型的约束应该保证memberListICacheMember类型的IEnumerable吗? 我是否真的需要将现有(但隐式) ICacheMember对象的集合转换为显式的 ICacheMember对象,然后将其转换回来? 我可以理解我可能需要根据Flubvert的方法签名将它们转换回来,但我不明白为什么我应该在方法调用中转换它们。 这就是我在工作代码中所做的事情,但它看起来完全不符合泛型的一般优雅行为,所以我认为我必须误解一下这应该如何操作。

首先, IEnumerable<out T> (和其他泛型类型)的协方差仅在T是引用类型时才有效,因此您需要:

public IEnumerable<ICacheMember> ExecuteFlubversion<T>(IEnumerable<T> memberList)
    where T: class, ICacheMember  // NOTE 'class'
{
    var flub = Flubvert(memberList);   // can you call with 'memberList'?
    return flub;                       // can you return that type?

    // depending on what 'Flubvert' does, maybe return 'IEnumerable<T>'
    // and say:
    // return (IEnumerable<T>)flub;
}

另请注意,我更改了返回值。 C#编译器不能保证来自非泛型Flubvert方法的返回对象比IEnumerable<ICacheMember>更具体。

让我们说你有:

interface ICacheMemberSub : ICacheMember
{
  ...
}

你可以这样称呼你的函数:

ExecuteFlubversion<ICacheMemberSub>(cacheMember);

此函数将尝试返回类型为IEnumerable<ICacheMember>的对象,并且不一定可以转换为IEnumerable<ICacheMemberSub> ,因此会出错。

有可能无法直接回答问题,您可以将Flubvert的签名更改为通用吗? 如果你使Flubvert通用,其余的方法代码将保持不变,你仍然可以假设成员将是ICacheMember的实现者。

public IEnumerable<T> Flubvert<T>(IEnumerable<T> members)
    where T : class, ICacheMember
{
    // do some stuff to members
    return members;
}


public IEnumerable<T> ExecuteFlubversion<T>(IEnumerable<T> memberList)
    where T : class,ICacheMember
{
    return Flubvert(memberList);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM