【问题标题】:calling method with list of subtype without casting使用子类型列表调用方法而不进行强制转换
【发布时间】:2015-11-16 13:26:11
【问题描述】:

电话

List<SubClazz> subList1 = new List<SubClazz>();
List<SubClazz> subList2 = new List<SubClazz>();
FuzzyCompareCollection(subList1,subList2); //Compile Error 

我是怎么做到的

FuzzyCompareCollection(subList1.Cast<SuperClazz>().ToList(),subList2.Cast<SuperClazz>().ToList()); 

方法定义

public static bool FuzzyCompareCollection<T>(List<T> list1, List<T> list2) where T : SuperClazz
    {
        if (list1.Count != list2.Count)
        {
            return false;
        }
        Dictionary<string, SuperClazz> dict1 = new Dictionary<string, SuperClazz>();
        Dictionary<string, SuperClazz> dict2 = new Dictionary<string, SuperClazz>();
        foreach (T item in list1)
        {
            dict1[item.ID] = item; //ID is an attribute of SuperClazz
        }
        foreach (T item in list2)
        {
            dict2[item.ID] = item;
        }

        bool equals = true;
        foreach (string key in dict1.Keys)
        {
            try
            {
                equals = Util.ReflectiveEquals(dict1[key], dict2[key]);
                if (!equals)
                {
                    break;
                }
            }
            catch (KeyNotFoundException e)
            {
                return false;
            }
        }
        return equals;
    }

我认为我应该能够调用该方法而无需将其转换为 SuperClazz,因为列表包含 SuperClazz 的子类型。 但是有办法吗?还是真的不可能,如果没有办法,你能向我解释为什么这行不通吗?

【问题讨论】:

  • 你能把 SuperClazz 和 SubClazz 的定义贴出来吗?或者更具体地说,它们之间的关系是如何定义的?
  • 与方法签名完美配合。请发布示例 SubClazz 和 SuperClazz 声明。可能是他们你缺少继承关系。
  • SubClazz 是否扩展了 SuperClazz?这应该。当它这样做时,代码编译没有错误。
  • 是的 SubClazz 正在扩展 SuperClazz 但我无法编译它。但问题已得到解答,无论如何感谢您的尝试。

标签: c# list generics casting subtype


【解决方案1】:

您需要使FuzzyCompareCollection 方法接受IReadonlyList&lt;T&gt; 类型的参数,而不是List&lt;T&gt;。这将起作用,因为与List&lt;T&gt; 相比,IReadonlyList&lt;T&gt; 是协变的。这意味着给定SubSuper 的子类型,IReadonlyList&lt;Sub&gt;IReadonlyList&lt;Super&gt; 的子类型,其中List&lt;Sub&gt; 不是List&lt;Super&gt; 的子类。

【讨论】:

  • 帮助。仍然无法理解 List 如何不是 List 的子类型,但你已经帮助了我 =)。当我有足够的信用时,我会支持你
  • List 不能是 List 的子类型,因为在某些情况下 List 实例不能作为 List 实例。具体来说,如果您有一个采用 List 并在其上调用 Add 方法的方法,则将 List 传递给此方法将意味着添加 Super 的实例(可能是也可能不是 Sub 的实例) 到 List,这是不允许的。 IReadonlyList 不存在这个问题,因为它是不可变的(没有 Add 方法)。
【解决方案2】:

缺少的部分大概是:

public class SubClazz : SuperClazz

您也不需要调用CastToList 方法。

【讨论】:

  • SubClazz 正在实现 SuperClazz,实际上您必须将列表强制转换为超类型,否则您将收到编译错误
猜你喜欢
  • 2016-11-07
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 2016-01-06
  • 2018-11-05
  • 1970-01-01
  • 2015-08-17
  • 2014-07-05
相关资源
最近更新 更多