【问题标题】:C#, Iterating over a common parent class for generic childrenC#,迭代通用子类的公共父类
【发布时间】:2014-06-03 18:54:08
【问题描述】:

我将如何设置以下类,以便我可以拥有一个采用公共父类/接口并允许我在不指定泛型类型的情况下迭代任何子类的方法?

public abstract class BaseClass
{ ??? }

public class ChildClass<T> : BaseClass 
{
    public List<T> SomeList;
            ???
}

ChildClass<int> childA = new ChildClass<int> ();
ChildClass<string> childB = new ChildClass<string> ();

public void IterateOverChild (BaseClass someChildClass)
{
    foreach (var element in someChildClass.SomeList)    
    {
        Console.WriteLine (element);
    }

}

【问题讨论】:

  • 你不能用正常的方式
  • BaseClass 不知道 ChildClass 上存在的任何属性。为什么不使 BaseClass 通用?换句话说——看起来你可以更好地抽象你想做的事情。
  • 泛型 BaseClass 的问题是你不能在没有泛型的代码中引用它。例如,您必须拥有void IterateOverChild&lt;T&gt;(BaseClass&lt;T&gt; someChildClass)。在很多情况下,您需要一个非泛型基类,因为泛型类型不可用。

标签: c# class generics foreach ienumerable


【解决方案1】:

让抽象类公开一些访问子类之间通用数据的方法,在这种情况下,是一个数据序列,其中每个对象可以是任何类型:

public abstract class BaseClass
{
    public abstract IEnumerable Data { get; }
}

public class ChildClass<T> : BaseClass
{
    public List<T> SomeList { get; set; }
    public override IEnumerable Data { get { return SomeList; } }
}

【讨论】:

    【解决方案2】:

    使用

    public abstract class BaseClass<T>
    {
        public List<T> SomeList { get; set; }
    
    }
    
    public class ChildClass<T> : BaseClass<T>
    {
    
    }
    
    public void IterateOverChild<T>(BaseClass<T> someChildClass)
    {
        foreach (var element in someChildClass.SomeList)
        {
            Console.WriteLine(element);
        }
    }
    

    【讨论】:

    • 这不一定是一个选项。例如,想象一下,他想要一个List&lt;BaseClass&gt;,其中每个基类都是不同的泛型类型。使用您的代码是不可能的。
    • 如果基类必须是非通用的,那么你的答案会更好
    【解决方案3】:

    除非BaseClass 知道&lt;T&gt;,否则它不能有任何T 类型的属性或方法。但是,您可以提供至少公开属性的非泛型形式的基本实现。您会丢失类型信息但保留可枚举性。

    public abstract class BaseClass
    {
        public IList SomeList { get; set; }
    }
    
    public class ChildClass<T> : BaseClass 
    {
        public new List<T> SomeList
        {
            get { return (List<T>) base.SomeList; }
            set { base.SomeList = value; }
        }
    }
    

    【讨论】:

    • 与其将范围狭窄的数据结构存储在容易出错的广泛定义的变量中,不如让广泛定义的成员成为范围更窄的存储位置的视图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 2014-01-26
    相关资源
    最近更新 更多