简体   繁体   中英

Set property of derived class on base class' instance

I have a base class like this:

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

... and two derived classes:

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

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

At compile time, I know that I'll be dealing with an object of type Document . However, it's only at runtime that I know whether it will be a Bill or a Quote .

I need to perform specific operations depending on the type, eg:

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

.. but I can't compile like that as the properties of the derived class is not accessible from a base instance.

What is the proper way of doing that? Here's a fiddle to play around .

myDoc.advance can only compile if the compiler can tell at compile time that myDoc is a Bill . Otherwise, myDoc is just a Document and that type does not have an advance member.

Doing a type check like that will not modify the static type of myDoc . Instead, you would have to type cast it into a Bill first:

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

Note that instead of using GetType() which checks the exact runtime type, you should be using the is operator to verify that myDoc is a Bill . You can even use the newer pattern matching syntax from C# to make this nicer:

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

Finally, please note that the common convention is to write properties in C# in PascalCase (ie Advance , Number , Sum and Discount ).

Also note that class members are private by default, so you still wouldn't be able to access those properties. So you would have to add a public in front of the property definitions.

Pattern matching is a good way to handle this if you are using C# 7.0+

if(myDoc is Bill bill)
{
    bill.Advance = 1000;
}
else if(myDoc is Quote quote)
{
    quote.Discount = 1000;
}

You can simply cast it:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM