Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C语言中变量的多态性#_C#_Oop_Polymorphism - Fatal编程技术网

C# C语言中变量的多态性#

C# C语言中变量的多态性#,c#,oop,polymorphism,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; s

有没有一种方法可以在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;
 }
有时,我将引用我的对象作为GameManager,有时作为BaseGameManager。当我将其作为游戏管理员引用时,我不想每次都将account属性强制转换为account类。那是我的问题。我说的泛型太多了,因为account不是继承我描述的方式的唯一属性

我确实知道泛型,但我认为它并不总是一个好的解决方案,因为你最终可能会得到这样的结果

这是一个完美的解决方案。如果你想动态地键入你的类,泛型是一种方法

您的类
A
只需要一个泛型类型参数,这对我来说似乎并不多。我有一些非常核心的基类,它们有相当多的泛型类型参数,但使用它们要比没有它们容易得多

拟议守则:

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

public class B : A<FinalClass>
{ }
公共类A,其中BC:基类
{
公共BC BaseClassProperty{get;set;}
}
B级:A级
{ }

您想要的内容违反了:


因此,在LSP适用的任何语言中,以您的示例演示的方式“变量的多态性”都是不合法的。当然,其他类型的多态性(例如,
B
a
的子类)也是可能的。

不,你不能像你的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();

您可以很容易地完成这项工作,但您需要使用“cheesy”
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; }
    }
}

如果你只需要把getter暴露在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; } }
}

这是一种新的味道,是不是很俗气?你如何编写程序而不实例化任何东西?@BradleyUffner他不是说
new
分配一个新对象,而是说
new
隐藏一个父变量。@BradleyUffner我怀疑OP的意思是如果你必须对多个变量使用
new
,我想说你的代码有一个设计问题。好吧,它是一个ORM映射器,所以你可以理解你有集合、行、字段、关系,这是4个最常见的…当然它很复杂,这就是为什么它上面的所有代码都是自动生成的。这样就省去了我们输入“相同”类300次:)。自动生成的类,这总是增加了乐趣:)好吧,我认为一个或两个泛型参数是可以的,但我认为在我的情况下,我可以得到超过5个。我个人会检查设计是否真的需要那么多泛型类型参数。看看是否可以重新设计某些零件,以便将它们连接在一起或省略。如果你真的需要这些,我看不出有5个有什么问题。这如何回答这个问题?@YuvalItzchakov:我认为隐含的“不”是显而易见的,但我为此添加了一句话。有趣的是,我几分钟前刚刚读完关于LSP的书,在回答时没有想到它。是时候多加注意了。这实际上是可行的,但是如果a被转换成B,那么你会得到一个异常。
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; }
    }
}
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; } }
}