簡體   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