2011-01-28 4 views
0

Я видел варианты этого вопроса раньше, но пока не нашел ответа.Создание экземпляров пользовательских классов во время работы неизвестного типа

У меня есть пользовательский класс:

public class Indicator 
{ 
    public double Value { get; set;} 

    virtual public void Calc(val1, val2) {} 
} 

И у меня есть много классов, производных от него, например:

class calc_sum : Indicator 
{  
    override public void Calc(val1, val2) 
    { 
    Value=val1+val2; 
    } 
} 

Наконец, у меня есть класс, чтобы держать все «Индикаторы»:

class IndicatorCollection 
{ 
    List<Indicator> _collection = new List<Indicator>(); 

    ...Some other methods here... 
} 

Что мне нужно, это предоставить метод в классе «IndicatorCollection», который принимает строку на основе имя класса, полученного из «Индикатора», и добавьте его в коллекцию. то есть:

IndicatorCollection.AddIndicator("calc_sum"); 

Таким образом, пользователь может добавлять индикаторы во время выполнения (The IndicatorsCollection является переплетено в список, который отображает свойство Value каждого члена).

Надеюсь, я был достаточно ясным и что я правильно подхожу. Спасибо всем

Update: Метод Активатор именно то, что я искал, поэтому я буду стараться сделать его более трудным:

После добавления экземпляра индикатора может IndicatorCollection выставить новый Свойство, которое является ярлыком для свойства Value класса.

т.е:

// After adding calc_sum to the collection, The IndicatorCollection class will have the following //property: 
public double calc_sum 
{ 
    get { return _collection.Find(i=>i.name=="calc_sym").First().Value; 
    // The indicator class also has a public member of "name" 
} 
+0

Ваш код не будет компилироваться как '' override' и virtual' ключевые слова не может быть первым в списке модификаторов. – Oded

+0

Я бы также сделал 'Индикатор' и абзац метода« Calc », основанный на вашем примере выше. –

+0

Я не думаю, что ваше новое требование может быть выполнено. Невозможно добавить свойства к существующему типу «на лету» с помощью C#. –

ответ

3

Если Indicator класса и его потомки разоблачить конструктор по без параметров, вы можете использовать Activator.CreateInstance() динамически создать экземпляр класса от его имени во время выполнения:

public class IndicatorCollection 
{ 
    public void AddIndicator(string className) 
    { 
     _collection.Add((Indicator) 
      Activator.CreateInstance(null, className).Unwrap()); 
    } 

    private List<Indicator> _collection = new List<Indicator>(); 
} 
0

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

var myIndicator = Activator.CreateInstance(Type.GetType("calc_sum")) as Indicator; 
0

Что касается второго требования (после обновления вашего), почему бы не использовать Dictionary<string, Inidicator> вместо List<indicator> хранить имена? Возможно, вы слишком усложняете свои требования.

public class IndicatorCollection 
{ 
    var _dictionary = new Dictrionary<string, Indicator>(); 

    public void AddIndicator(string className) 
    { 
     _dictionary.Add(
      className, 
      (Indicator)Activator.CreateInstance(null, className).Unwrap() 
     ); 
    } 
} 

, а затем ...

public double GetValue(string indicatorName) 
{ 
    return _dictionary[indicatorName].Value; 
} 
+0

Причина, по которой я хочу, чтобы это свойство: В настоящее время список привязан к ItemsCollection. Я хочу вместо этого привязать его к отдельным элементам, то есть: {Binding IndicatorCollectionInstance.calc_sum} – Sol

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