views:

293

answers:

2

So if class C inherited from class B and has one extra property, could I create a new object of class C by passing it an object that already exists of class B and it will either leave the extra property null or run some LINQ to SQL to see what the extra property should be (such as for a counter, etc)?

C c = new C();
B b = bRepo.getBbyID(id);
c = b;
c.extraProperty = bRepo.getCountBybID(b.ID);

If that would work could I do the same with an IQueryable of Cs and Bs?

A: 

You cannot do that in the way you specified. To achieve the same result you could copy over all properties from the B instance to the C instance and then set the new property. However, this is often and indication that you may want to rethink your object model. For instance, you can have C have a B on it and additional properties instead of C being a B. This makes sense for something like a counter as the new property. You can have a class hierarchy like this:

class B
{
    string SomeValue1 { get; set; }
    int SomeValue2 { get; set; }
    decimal SomeValue3 { get; set; }
} 

interface ICountable<T>
{
    T Value { get; }
    int Count { get; }
}

class C : ICountable<B>
{
    B Value { get; set; }
    int Count { get; set; }
}
eulerfx
+3  A: 

No. A B is not guaranteed to be a C, so you cannot store a B in a variable that can hold only Cs. (An Animal is not guaranteed to be a Llama, so you can't create a generic Animal and store it in a Llama variable.)

However, you could provide a way of constructing a C instance from a B -- either by having the C copy the properties from the B, or by having the C store the B as a private member, and delegate property getters and setters to the contained B. Then your code would look like:

B b = brepo.GetBById(id);
C c = new C(b);
c.extraProperty = brepo.GetCountByBId(b.Id);

The same issue applies with an IQueryable of Bs. If they're not actually Cs, you can't pretend they are, not set extraProperty on them. What you can do is select those which are Cs using the OfType operator, try to cast them to Cs using the Cast operator, or create new Cs from the queried Bs using the Select operator and one of the techniques mentioned above, e.g. bs.Select(b => new C(b)).

itowlson