有没有办法在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类。那是我的问题。我说的是泛型太多了,因为帐户不会是继承我描述的方式的唯一属性。
答案 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持有的任何语言中都不合法。当然,其他类型的多态(例如,B
是A<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; } }
}