2017-02-09 3 views
0

У меня есть 2 классов, которые унаследованы таким образомДоступ класс ребенка свойства

public class PartsParent 
{ 

} 
public class PartsCar : PartsParent 
{ 
    public int WheelRadius { get; set; }  
    public int Price { get; set; } 
} 

public class PartsBike : PartsParent 
{ 

    public int Length { get; set; }  
    public int Weight { get; set; }  
    public int Price { get; set; } 
} 

И у меня есть функция, которая принимает класс PartsParent в качестве параметра, и как я могу преобразовать это как partsCar/в PartsBike внутри функции и свойства доступа, такие как Price WheelRadius и т. д.?

private int PriceCollection(PartsParent mainObject) 
{ 

    int _price=0; 
    mainObject.OfType(PartsCar).Price;// something similar?? 
    return _price; 
} 
+0

'((PartsCar) mainObject) .WheelRadius' должны быть разработаны. Однако, если вы должны подвергнуть объект дочернему типу, попробуйте его перепроектировать. –

+2

Кстати, вы должны определить 'Price' в' PartsParent', так как все ваши дочерние типы нуждаются в цене. Если это так, вы можете получить доступ к 'mainObject.Price' без его преобразования. –

+0

@ J.C Да, вы правы в том, что общие свойства должны быть частью только класса родителя, а свойства объекта, о которых идет речь, являются только образцом. Ваше предложение решило мою проблему –

ответ

2

Ну, вы пытаетесь придать родительский тип дочернему типу, что на самом деле невозможно, почему?

Ответ заключается в том, что родительский P, который вы пытаетесь передать ребенку C1, может быть фактически и первоначально из типа C2, поэтому приведение будет недействительным.

Лучший способ объяснить это фраза, которую я прочитал где-то здесь, на StackOverflow

Вы не можете бросить млекопитающее в собаку - это может быть кошка.

Вы не можете бросить пищу в бутерброд - это может быть чизбургер.

Что вы можете сделать, хотя повернуть вокруг этой ситуации что-то вроде этого:

(mainObject is PartsCar) ? (PartsCar)mainObject : mainObject 

Что эквивалентно:

mainObject as PartsCar 

Затем доступ к результату броска mainObject с помощью цифровых null coalescing operator (потому что если как не удается, результат литья будет null, а не бросает исключение).

Общий метод OfType<T>, который вы пытались использовать, - это метод расширения, который может быть использован с объектами типа IEnumerable<T'>, который, я думаю, не ваш случай.

1

Идея наследования состоит в том, чтобы группировать то, что принято в суперклассе, и оставлять другие конкретные детали для подклассов. Так что если свойство, скажем Price, исключено из всех подклассов, то оно должно быть объявлено в суперклассе.

Однако, если вы все еще хотите использовать его таким образом, то, что вы ищете это:

int _price = ((PartsCar)mainObject).Price; 

Однако, что если объект был какой-то другой класс, скажем PartsGift, который наследуется от PartsParent, но не имеет цены? Тогда он рухнет.

Вам почти действительно нужно проверить свой дизайн.

BTW, если вы хотите проверить, действительно ли объект имеет определенный класс, вы можете использовать is.

int number = 1; 
object numberObject = number; 
bool isValid = numberObject is int; // true 
isValid = numberObject is string; // false 
0

Вы можете использовать is ключевое слово, чтобы проверить тип и as ключевое слово, чтобы преобразовать в целевой тип ребенка следующим образом.

if (mainObject is PartsCar) 
{ 
    var partscar = mainObject as PartsCar; 
    // Do logic related to car parts 
} 
else if (mainObject is PartsBike) 
{ 
    var partsbike = mainObject as PartsBike; 
    // Do logic related to bike parts. 
} 
0

Это возможно, если вы разделите незаурядные Свойства кода в блок:

if (mainObject is PartsCar) 
{ 
    //Seprated code for PartsCar 
    // WheelRadius... 
    //Price... 
} 
else if (mainObject.GetType() == typeof(PartsBike)) 
{ 
    //Seprated code for PartsBike 
    //Length 
    //Weight 
    //Price 
}