C# 中变量的多态性
本文关键字:多态性 变量 | 更新日期: 2023-09-27 18:32:30
有没有办法在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。当我将其引用为游戏管理器时,我不想每次都将帐户属性强制转换为帐户类。这是我的问题。我说泛型太多了,因为 account 不会是继承我描述的方式的唯一属性。
我确实知道泛型,但我认为这并不总是一个好的解决方案,因为您最终可能会得到这样的东西
嗯,这是一个完美的解决方案。如果要动态键入类,则泛型是要走的路。
您类A
只需要一个泛型类型参数,这对我来说似乎并不多。我有一些非常核心的基类,它们有很多泛型类型参数,而且使用起来比没有它要容易得多。
建议的代码:
public class A<BC> where BC : BaseClass
{
public BC BaseClassProperty {get; set;}
}
public class B : A<FinalClass>
{ }
不,你不能做像你的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();
你想要
的违反了Liskov替换原则:
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>
的子类)是可能的。
您可以非常轻松地完成这项工作,但是,您需要使用"俗气"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; }
}
}
如果你只需要在 A 和 b 中公开的 getter,你可以做这样的事情。
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; } }
}