继承自基于泛型类但需要派生类的类类型的类

时间:2010-01-13 17:34:55

标签: c# generics

我有一个问题,不太确定如何解决它..

考虑课程:

public class BaseClass<T>
{

    public T PreviousInstance { get; set; }

}

现在我的辅助数据类:

public class DataClass : BaseClass<DataClass>
{
    public bool ABoolProperty { get; set; }
}

所以我有DataClass(在WMI对象更改时通过LINQ To WMI桥接填充),当从更改事件填充时,在编辑之前提供已更改的数据和先前的数据,这非常有用。 我现在有第三堂课:

public class DerivedDataClass : DataClass
{
    public string AStringProperty { get; set; }
}

我的问题是DerviedDataClass.PreviousInstance仍然是DataClass类型,这意味着我不会获得在DerivedDataClass中声明的PreviousInstance的任何属性。

我考虑过声明DataClass即

public class DataClass<T> : BaseClass<T>

这将允许DerivedDataClass中的属性在PreviousInstance中可用。 但是我仍然需要能够自己使用DataClass而不必声明它:

DataClass<DataClass<object>>

只是为了让它工作我真正想要的是拥有该类的通用版本和非通用版本,而不必声明具有相同属性的2个单独的类。

那么任何想法? :)

6 个答案:

答案 0 :(得分:3)

继承层次结构用于模拟“我可以在任何需要基类实例的地方使用派生类的实例”的概念,对吗?如果你有一个采用Fruit的方法,那么你可以将它传给Apple,并且知道没有问题。

让我们简化您的代码。

class B<T>
{
    public T Another { get; set; }
}
class Fruit : B<Fruit> {}
class Apple : Fruit {}
class Orange : Fruit {}

现在,Apple.Another的类型是Fruit,而不是Apple类型。它必须是Fruit类型,因为你可以有一个方法

void AddAnOrange(Fruit f)
{
    f.Another = new Orange();
}

即使您传入Apple ,也必须工作 - Fruit的合同是 a Fruit指的是任何其他水果,而不是“水果指的是另一种衍生类型的果实,直到运行时才知道。

如果你需要建立关系模型“一个苹果指的是另一个苹果,一个橙色指的是另一个橙子”,那么就不要这样说“一个水果是指另一个水果”;这不是捕捉你想要正确建模的东西,而是会让你以后痛苦。

答案 1 :(得分:2)

您可以采取以下方法: -

public interface IPreviousInstance<T>
{
    T PreviousInstance { get; set; }
}

public class DataClass : IPreviousInstance<DataClass>
{
    public DataClass PreviousInstance { get; set; }
    public bool ABoolProperty { get; set; }
}

public class DerivedDataClass : DataClass, IPreviousInstance<DerivedDataClass>
{
    public new DerivedDataClass PreviousInstance { get; set; }
    public string AStringProperty { get; set; }
}

答案 2 :(得分:0)

您可以尝试隐藏属性,如下所示:

public class DerivedDataClass : DataClass
{
  new public DerivedDataClass PreviousInstance
  {
     get { return (DerivedDataClass)base.PreviousInstance; }
     set { base.PreviousInstance = value; }
  }
}

如果PreviousInstance的类型不正确,您将收到错误消息。注意:您不能将DerivedDataClass的实例称为其基类型DataClass,因为它将使用PreviousInstance的DataClass版本,并绕过阴影。

答案 3 :(得分:0)

你想要什么是不可能的,因为不允许多重继承。

您可以做的是从基类继承泛型类型参数,如

public class DataClass<T> : BaseClass<T>

根据您想要实现的目标,这可以为您提供帮助。请记住,泛型不是像源代码的模板文本那样使用。

答案 4 :(得分:0)

目前我能看到的唯一方法是在链中引入另一个层:

public abstract class AbstractDataClass<T> : BaseClass<T>
{ 
   public bool ABoolProperty { get; set; }
}

public class DataClass : AbstractDataClass<DataClass>
{
}

public class DerivedClass : AbstractDataClass<DerivedClass>
{
   public string AStringProperty { get; set; }
}

虽然我承认它非常笨重,特别是当你开始进入等级增加层次时

答案 5 :(得分:0)

感谢响应人员,但非解决方案完全符合我的需要。 我正在制作的图书馆将由我的团队使用,如果他们需要派生他们自己的数据,那么它需要是自动的,所以他们不必深入了解必须实现接口或阴影属性。

我决定做的是添加另一个类decleration,以便最终开发人员可以使用泛型(用于派生类)或非泛型用于在他们的应用程序中直接使用。

例如:

public class DataClass<T> : BaseClass<T>
{
    public bool ABoolProperty { get; set; }
}

public class DataClass : DataClass<DataClass>  
{
}