2016-01-20 4 views
0

У меня есть массив элементов:C# тип переменной. (Переменная)

Item[] ItemsOut; 

Проблема в том, у меня есть некоторые производные типы Item, как EquipItem. Они тоже в этом массиве.

У меня есть функция AddItem для обоих классов Item и EquipItem.

Inventory.AddItem(AllRecipes.Recipes[curPage].ItemsOut[i]......); 

Идея заключается в том, что в случае, если мой массив типа Item[] поэтому всегда добавлять элементы, такие как нормальный Item.

Мое текущее решение работает, и это:

if (AllRecipes.Recipes[curPage].ItemsOut[i].GetType() == typeof(EquipItem)) 
{ 
    Inventory.AddItem((EquipItem)AllRecipes.Recipes[curPage].ItemsOut[i], AllRecipes.Recipes[curPage].ItemsOut[i].number); 
} 
else 
{ 
    Inventory.AddItem(AllRecipes.Recipes[curPage].ItemsOut[i], AllRecipes.Recipes[curPage].ItemsOut[i].number); 
} 

Но если у меня есть 100500 ребенка классы я буду вынужден делать 100500 if заявления.

Как сделать это автоматическим? Что-то вроде:

Inventory.AddItem((AllRecipes.Recipes[curPage].ItemsOut[i].GetType())AllRecipes.Recipes[curPage].ItemsOut[i], AllRecipes.Recipes[curPage].ItemsOut[i].number); 

или

Inventory.AddItem(AllRecipes.Recipes[curPage].ItemsOut[i] as AllRecipes.Recipes[curPage].ItemsOut[i].GetType(), AllRecipes.Recipes[curPage].ItemsOut[i].number); 

Я хотел бы быть в состоянии сделать что-то вроде:

Type t = AllRecipes.Recipes[curPage].ItemsOut[i].GetType(); 
Inventory.AddItem((t)AllRecipes.Recipes[curPage].ItemsOut[i].number); 

Но это вызывает «переменную, используемую в качестве типа» ошибка, когда Мне НЕОБХОДИМО использовать его как тип. Конечно, не переменная, а ее ценность.

+4

Почему вы литье вообще? Что делает 'AddItem (EquipItem)' по-разному 'AddItem (Item) '? –

+0

В общем, то, что вы пытаетесь сделать, - это просто то, что система типа C# не особенно хорошо подходит для обработки. См. [Эту серию статей] (http://ericlippert.com/2015/04/27/wizards-and-warriors-part-one/) по теме, которая углубляется в объяснение, почему это проблема, что некоторые из решений являются, и почему ни один из них не особенно велик (в C# в любом случае). – Servy

+0

AddItem (EquipItem) добавляет элемент и делает его equipable, nonstackable, e.t.c. Когда AddItem (Item) делает его обычным элементом. Большое спасибо за статьи. И, кстати, эта работа модератора просто потрясающая, я очень ее ценю. –

ответ

1

Во-первых, УНЛ - некоторые действия, основанные на типе, снова вызывающий код не должен ничего о типе знаю ESS вы два метода с именем AddItem (один для пункта, а другой для EquipItem) вам не нужно, чтобы бросить свой ItemsOut, просто используйте Inventory.AddItem(AllRecipes.Recipes[curPage].ItemsOut[i], AllRecipes.Recipes[curPage].ItemsOut[i].number);

Во-вторых, вы не можете сделать это:

Type t = AllRecipes.Recipes[curPage].ItemsOut[i].GetType(); 
addItem((t)AllRecipes.Recipes[curPage].ItemsOut[i] 

потому что t является экземпляром класса Type, можно отливать, используя только имя типа, как (EquipItem) AllRecipes.Recipes[curPage].ItemsOut[i]

И, наконец, если вы не испытываете проблем с производительностью, никогда не пытаются оптимизировать свой код.Делать так, что мы называем Premature Optimization

Итак, проверьте, есть ли у вас метод AddItem(EquipItem equipItem). Если вы этого не сделаете, вам не нужно проверять его тип и наложить элемент на EquipItem. Надеюсь, я могу тебе помочь.

EDIT лучшее, что я могу думать, что может улучшить ваш код очищает его немного, как это:

var item = AllRecipes.Recipes[curPage].ItemsOut[i]; 
if (item is EquipItem) 
{ 
    Inventory.AddItem((EquipItem) item, item.number); 
} 
else 
{ 
    Inventory.AddItem(item, item.number); 
} 
+1

AddItem (EquipItem equipItem) - yes, ofc Я получил этот метод. Вы мне очень помогли, «если у вас нет проблем с производительностью, никогда не пытайтесь оптимизировать свой код». Thats кажется сумасшедшим для такого Perfectionist как я, но я прочитаю статью и, вероятно, пойму, что это правильно. –

+0

@ mir-bot Да, трудно понять это, но поверьте мне, это вам очень поможет. Хотя оптимизация кода нежелательна, рекомендуется улучшить его читаемость. В этом случае мое последнее редактирование может помочь. – dcidral

1

Идея здесь заключается не в том, чтобы что-либо знать о разнице между Item, EquipItem (или, впрочем, любой старый FooItem).

Если все они вытекают из Item и массив набран, как Item[] то эти подклассы могут быть добавлены в массив без проблем

var item = new Item(); 
var equip = new EquipItem(); // where EquipItem inherits from Item; 
var array = new Item[]{ item,equipItem}; // no error here 

Если у вас есть один AddItem метод, который добавляет к этому массиву и преформ возможно, некоторые виртуальный метод, который делает некоторые действия при добавлении в список

public class Item 
{ 
    public virtual void AddedToList(){} 
}  

public class EquipItem 
{ 
    public override void AddedToList() 
    { 
     // behaviour specific to EquipItem 
    } 
} 
+0

Проблема в том, что я использую единство и массив Item [], заполняющий функцию GetComponents, которая возвращает массив элементов –

+0

@MirBot. Я не вижу, как это имеет значение для этого ответа. – Jamiec

+0

Это называется полиморфизм, и если это не сработало, как упоминал Джемак, никто из нас не будет использовать сам C#. – niksofteng

Смежные вопросы