C#中变量的多态性

时间:2016-01-29 14:26:07

标签: c# oop polymorphism

有没有办法在C#中实现变量的多态?

基本上我想写这样的东西:

public class BaseClass
{
}

public class FinalClass : BaseClass
{
}

public class A
{
   public BaseClass BaseClassProperty {get; set;}
}

public class B : A
{
   public override FinalClass BaseClassProperty {get; set;}
}

我确实知道泛型,但我觉得它并不总是一个很好的解决方案,因为你最终会得到这样的东西 -

 public class A<T,V,C>
 {
    public T TValue;
    public V VValue;
    public C CValue;
 }

我也知道关键词“新”,但我发现它太“俗气”。

编辑: 我将解释我的情况以避免XY问题。

public abstract class BaseGameManager
{
    public BaseAccount account;
}                         

public abstract class BaseAccount
{
}

public class GameManager : BaseGameManager
{
    public Account account;
}                         

public class Account : BaseAccount
{
}

有时候,我会将我的对象引用为GameManager,有时也会引用为BaseGameManager。当我将它称为GameManager时,我不想每次都将帐户属性转换为Account类。那是我的问题。我说的是泛型太多了,因为帐户不会是继承我描述的方式的唯一属性。

5 个答案:

答案 0 :(得分:1)

  

我确实知道泛型,但我认为它并不总是一个好的解决方案,因为你最终会得到类似的东西

嗯,这是一个完美的解决方案。如果要动态键入类,可以使用泛型。

你的类A只需要一个泛型类型参数,这对我来说似乎不是很多。我有一些非常核心的基类,并且它们有相当多的泛型类型参数,但是如果我没有它,它仍然比使用它更容易。

建议代码:

public class A<BC> where BC : BaseClass
{
   public BC BaseClassProperty {get; set;}
}

public class B : A<FinalClass>
{ }

答案 1 :(得分:0)

您想要的内容违反了Liskov substitution principle

var x = new B();

A a = x;  // works, because B is a subtype of A

// Compiles, since BaseClassProperty is of type BaseClass,
// but fails, since B only accepts a FinalClass.
a.BaseClassProperty = new BaseClass();

所以,不,“你的示例所展示的方式的变量”的多态性在LSP持有的任何语言中都不合法。当然,其他类型的多态(例如,BA<FinalClass>的子类)也是可能的。

答案 2 :(得分:0)

不,你不能像你的A / B例子那样做。这是一个为什么它不能工作的例子:

A actuallyA = new A();
A actuallyB = new B(); // Totally legal

actuallyA.BaseClassProperty = new BaseClass();
actuallyA.BaseClassProeprty = new FinalClass();

actuallyB.BaseClassProperty = new FinalClass(); // What B allows
// Because actuallyB is referenced locally as an A, that definition would allow it,
// however this would fail because B only allows the one base type.
actuallyB.BaseClassProperty = new BaseClass();

答案 3 :(得分:0)

你可以很容易地完成这项工作但是,你需要使用“俗气”new

class Program
{
    static void Main(string[] args)
    {
        A a = new B();

        a.Prop = new MyBase();

        Console.WriteLine("'{0}'", a.Prop); // 'classtest.MyBase'
        Console.WriteLine("'{0}'", ((B)a).Prop); // ''

        a.Prop = new Final();
        Console.WriteLine("'{0}'", a.Prop); // 'classtest.Final'
        Console.WriteLine("'{0}'", ((B)a).Prop); // 'classtest.Final'
    }
}

public class MyBase
{
}
public class Final : MyBase
{
}

public class A
{
    public MyBase Prop { get; set; }
}
public class B : A
{
    public new Final Prop
    {
        get { return base.Prop as Final; }
        set { base.Prop = value; }
    }
}

答案 4 :(得分:0)

如果您只需要在A和B中暴露的吸气剂,您可以做这样的事情。

public class BaseClass
{
}

public class FinalClass : BaseClass
{
}

public class A
{
    private BaseClass baseProp;
    public virtual BaseClass BaseClassProperty {get { return baseProp; } }
}

public class B : A
{
    private FinalClass finalProp;
    public override BaseClass BaseClassProperty {get { return finalProp; } }
}