2013-06-27 4 views
1

В программе инвентаризации я сделал классы Item и ItemCollection, а также производный класс Computer : Item.C# Наследование - дифференцирование производного объекта из базового объекта

В форме я создаю ItemCollection (общий список Item с) называется TheseItems (в том числе некоторых компьютеров), и я хочу, чтобы отобразить свойства каждого элемента ThisItem (например, расположение, количество и т.д.).

Выполняя это, я хочу также отображать различные свойства для компьютеров (таких как процессор, жесткий диск и оперативная память). У меня это до сих пор:

foreach (Item ThisItem in TheseItems) 
{ 
    //Display properties of Item instance “ThisItem” (Excluded for ease of reading) 

    if (ThisItem is Computer) 
    { 
     //Display distinct properties of Computer instance “ThisItem” 
    } 
} 

До сих пор ошибок не было, но я не уверен, как действовать дальше. Можно ли делать то, что я хочу?

EDIT: Спасибо, стейк! Я был обеспокоен тем, что кастинг не позволит мне получить доступ к предварительно назначенным свойствам (и просто разрешить назначать новые), но я, к счастью, ошибся! У меня теперь есть:

Computer ThisComputer = ThisItem as Computer; 
if (Computer != null) 
{ 
    //Display distinct properties of Computer instance “ThisComputer” 
} 

Я действительно впечатлен быстрой помощью, которую я получил. Благодаря!

+0

У вас будет работать. –

ответ

1

У вас будет работать.

foreach (Item ThisItem in TheseItems) 
{ 
    //Display properties of Item instance “ThisItem” (Excluded for ease of reading) 

    if (ThisItem is Computer) 
    { 
     Computer computerItem = (Computer)ThisItem; 
     //Display distinct properties of Computer instance “ThisItem” 
    } 
} 

Или используйте as ключевое слово для небольшой оптимизации:

foreach (Item ThisItem in TheseItems) 
{ 
    //Display properties of Item instance “ThisItem” (Excluded for ease of reading) 
    var computerItem = ThisItem as Computer; 
    if (computerItem != null) 
    { 
     //Display distinct properties of Computer instance “ThisItem” 
    } 
} 

Кроме того, мой друг написал хороший класс утилита для помогает с этим. Я думал, что опубликую его, так как это оказалось очень полезным.

foreach (Item ThisItem in TheseItems) 
{ 
    //Display properties of Item instance “ThisItem” (Excluded for ease of reading) 
    ThisItem.Match() 
      .Case<Computer>(comp => /* Do stuff with your computer */) 
      .Case<Television>(tv => /* Do stuff with your television */) 
      .Default(item => /* Do stuff with your item */); 
} 

Класс полезности выглядит примерно так. Ниже дается суть, и она очень расширяема.

public class Matcher<TMatch> 
{ 
    private readonly TMatch _matchObj; 
    private bool _isMatched; 

    public Matcher(TMatch matchObj) 
    { 
     this._matchObj = matchObj; 
    } 

    public Matcher<TMatch> Case<TCase>(Action<TCase> action) where TCase : TMatch 
    { 
     if(this._matchObj is TCase) 
     { 
      this.DoCase(() => action((TCase)this._matchObj)); 
     } 
     return this; 
    } 

    public void Default(Action<TMatch> action) 
    { 
     this.DoCase(() => action(this._matchObj)); 
    } 

    private void DoCase(Action action) 
    { 
     if (!this._isMatched) 
     { 
      action(); 
      this._isMatched = true; 
     } 
    } 
} 

public static class MatcherExtensions 
{ 
    public static Matcher<TMatch> Match<TMatch>(this TMatch matchObj) 
    { 
     return new Matcher<TMatch>(matchObj); 
    } 
} 
+0

Просто избили меня. Мой ответ - DITTO. –

+2

Идиоматический способ сделать то же самое: иметь компьютер ComputerItem = ThisItem as Computer; if (computerItem! = null) {...} '. Оператор 'is' фактически выполняет операцию' as', а затем проверяет его на 'null', поэтому' '' '', за которым следует бросок, на самом деле требует дополнительной инструкции. – dlev

0

Да, только внутри вашего предложения IF, отнесенного к вашему производному классу, и свойства будут доступны.

foreach (Item ThisItem in TheseItems) 
{ 
    //Display properties of Item instance “ThisItem” (Excluded for ease of reading) 

    if (ThisItem is Computer) 
    { 
     var ThisComputer = (Computer) ThisItem; 
     Display(ThisComputer.CPU); 
     //etc 
    } 
} 
1

Это подход, который я обычно использую. Это может быть немного быстрее, чем проверка типа и затем литье (у меня нет доказательств этого).

foreach (Item ThisItem in TheseItems) 
{ 
    //Display properties of Item instance “ThisItem” (Excluded for ease of reading) 

    var computer = ThisItem as Computer; 
    if (computer != null) 
    { 
     //Display distinct properties of Computer instance “ThisItem” 
    } 
} 
1

Сообщите, не спрашивайте.

Не спрашивайте ThisItem для его свойств, так что вы можете написать их, скажите, чтобы написать их для вас

foreach (Item ThisItem in TheseItems) 
{ 
    ThisItem.DisplayProperties(Console.out); 
} 

Затем сделать DisplayProperties() виртуальными, и перегрузить его в Computer включать свойства исключительных к нему ,

+0

+1 Это часто лучший ответ для этих проблем, но не всегда. Вероятно, это даже лучший ответ для OP. –