В C # вы можете создать новый унаследованный объект, присвоив ему копию своего базового объекта? - PullRequest
0 голосов
/ 05 октября 2009

Так что, если класс C унаследован от класса B и имеет одно дополнительное свойство, могу ли я создать новый объект класса C, передав ему объект, который уже существует класса B, и он либо оставит дополнительное свойство пустым, либо запустит какой-нибудь LINQ в SQL, чтобы увидеть, каким должно быть дополнительное свойство (например, для счетчика и т. д.)?

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

Если бы это сработало, могу ли я сделать то же самое с IQueryable из Cs и Bs?

Ответы [ 2 ]

3 голосов
/ 05 октября 2009

Нет. A B не гарантируется как C, поэтому вы не можете хранить B в переменной, которая может содержать только C. (Животное не обязательно является ламой, поэтому вы не можете создать универсальное животное и сохранить его в переменной ламы.)

Однако вы могли бы предоставить способ построения экземпляра C из B - либо с помощью C скопировать свойства из B, либо с помощью C, сохраняющего B как частный член, и делегирующего свойства get и устанавливает сеттер на B. Тогда ваш код будет выглядеть так:

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

Та же проблема относится к IQueryable из Bs. Если они на самом деле не C, вы не можете притворяться, что они есть, и не устанавливать для них extraProperty. Что вы можете сделать, это выбрать те, которые являются C, с помощью оператора OfType, попытаться привести их к C, используя оператор Cast, или создать новые C из запрашиваемых B, используя оператор Select и один из методов, упомянутых выше, например, bs.Select(b => new C(b)).

0 голосов
/ 05 октября 2009

Вы не можете сделать это так, как вы указали. Для достижения того же результата вы можете скопировать все свойства из экземпляра B в экземпляр C, а затем установить новое свойство. Однако это часто и указывает на то, что вы можете переосмыслить свою объектную модель. Например, у вас может быть C с буквой B и дополнительными свойствами, а не C с буквой B. Это имеет смысл для чего-то вроде счетчика как нового свойства. Вы можете создать иерархию классов следующим образом:

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; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...