在基类的实例上设置派生类的属性

时间:2018-09-18 22:38:50

标签: c#

我有一个像这样的基类:

class Document {
    int number {get; set;}
    double sum {get; set;}
}

...和两个派生类:

class Bill : Document {
    double advance {get; set;}
}

class Quote : Document {
    double discount {get; set;}
}

在编译时,我知道我将处理Document类型的对象。但是,只有在运行时才知道它是Bill还是Quote

我需要根据类型执行特定的操作,例如:

if (myDoc.GetType() == typeof(Bill)) {
   myDoc.advance = 1000; //<-- can't find "advance"
}

..但是我不能那样编译,因为无法从基实例访问派生类的属性。

这样做的正确方法是什么? 这是fiddle to play around

3 个答案:

答案 0 :(得分:3)

myDoc.advance仅在编译器可以在编译时告知myDocBill的情况下才可以编译。否则,myDoc只是Document,并且该类型没有advance成员。

进行类似的类型检查不会修改myDoc的静态类型。相反,您必须先将其类型转换为Bill

Bill myBill = (Bill)myDoc;
myBill.advance = 1000;

请注意,您应该使用GetType()运算符来验证ismyDoc,而不是使用Bill来检查确切的运行时类型。您甚至可以使用C#中较新的模式匹配语法来使它变得更好:

if (myDoc is Bill myBill) {
    myBill.advance = 1000;
}

最后,请注意,通用约定是在PascalCase中用C#编写属性(即AdvanceNumberSumDiscount)。

还请注意,默认情况下,班级成员是私有,因此您仍然无法访问这些属性。因此,您必须在属性定义之前添加一个public

答案 1 :(得分:2)

如果您使用的是C#7.0+,则模式匹配是处理此问题的好方法

prop

答案 2 :(得分:1)

您可以简单地投射它:

if (myDoc.GetType() == typeof(Bill))
{
    ((Bill)myDoc).advance = 1000;
}