在c#中,有没有办法写一个泛型,如Object <child>:Object <parent>?</parent> </child>

时间:2010-07-20 18:04:10

标签: c# .net generics

有没有办法在c#中做这样的事情?请考虑以下示例,并假设Child1,Child2,Child3都是Parent的子项 -

class Class1
{

  SomeObject< Parent > mSomeObject; 

  Class1()
  {

     if (condition1)

          mSomeObject = new SomeObject<Child1>();

     else if (condition2) 

          mSomeObject = new SomeObject<Child2>(); 

     else if (condition3) 

          mSomeObject = new SomeObject<Child3>();

  }

}

这个想法是Class1会将SomeObject作为成员,但是在运行时它不确定它应该采用SomeObject的通用形式。任何帮助,将不胜感激。谢谢!

4 个答案:

答案 0 :(得分:3)

您应该使用基于接口的继承。这将允许child1,child2和child3具有多态性,并且不需要这样的保护逻辑就可以采用父类的特征。随着IF测试的结束,您的代码将更易读,更容易在以后修改。

以下是我刚用LINQPad编写的示例,以示明这一点。

public interface ICar
{
    bool IsAutomatic();
}

public class Silverado : ICar
{
    public bool IsAutomatic()
    {
        return true;
    }
}

public class Semi : ICar
{
    public bool IsAutomatic()
    {
        return false;
    }
}

void Main()
{
    ICar car = new Silverado();
    bool isAuto = car.IsAutomatic();
    isAuto.Dump();

    car = new Semi();
    isAuto = car.IsAutomatic();
    isAuto.Dump();
}

输出:

True
False

我更喜欢基于接口的继承,而不是AllenG所描述的抽象类。多重继承的原因 - 一个类可以实现许多接口,但只能从1个类继承。

希望这会有所帮助......

答案 1 :(得分:2)

你可以这样做。请注意,此处使用out关键字可以使类型变为协变。

public interface ISomeObject<out T>
{
}

但是,这会限制您在界面中使用T可以执行的操作。具体而言,您只能声明T处于输出位置的成员。换句话说,它不能被接受为函数的参数。

答案 2 :(得分:1)

我从未尝试过,但我相信你是对的。一般来说,如果

public class Child : Parent

然后Parent

将满足对Child.的任何调用

例如:

public class Animal { //stuff }
public class Cat : Animal { // overridden stuff }

List<Animal> pets = new List<Animal>;
pets.Add(new Cat());

会起作用。

如果您正在寻找行为,您可能希望使用Interfaces而不是类继承,但它的工作方式相同。

不,您的方法可能遇到的问题是您的SomeObject<Parent>只能访问您的Parent类中的成员。要在相应的Child类中使用任何内容,您需要转换回相应的Child。

答案 3 :(得分:1)

您可以使用接口或委托在C#4.0中执行此操作,但不能在类中执行此操作。考虑将属性更改为接口类型,并在C#4.0中阅读有关泛型协方差和逆变的更多信息(例如:http://msdn.microsoft.com/en-us/library/ee207183.aspx