Reputation: 365
I saw variants of this question before, but didn't find answer yet.
I have a custom class:
public class Indicator
{
public double Value { get; set;}
virtual public void Calc(val1, val2) {}
}
And I have many classes derived from it, such as:
class calc_sum : Indicator
{
override public void Calc(val1, val2)
{
Value=val1+val2;
}
}
Finally, I have a class to hold all "Indicators":
class IndicatorCollection
{
List<Indicator> _collection = new List<Indicator>();
...Some other methods here...
}
What I need, is to provide a method in the "IndicatorCollection" class which accepts a string based name of a class derived from "Indicator" and add it to the _collection. i.e:
IndicatorCollection.AddIndicator("calc_sum");
That way the user can add indicators at runtime (The IndicatorsCollection is binded to a list which displays the Value property of each member).
I hope I was clear enough and that I am taking the right approach. Thank you all
Update: The Activator method is exactly what I was looking for, So I'll try to make it more difficult:
After adding the Indicator instance, can IndicatorCollection expose a new Property which is a shortcut to the class's Value property.
i.e:
// 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"
}
Upvotes: 0
Views: 1502
Reputation: 53396
Regarding the second requirement (after your update), why not use a Dictionary<string, Inidicator>
instead of List<indicator>
to store the names? Maybe you are over complicating your requirements.
public class IndicatorCollection
{
var _dictionary = new Dictrionary<string, Indicator>();
public void AddIndicator(string className)
{
_dictionary.Add(
className,
(Indicator)Activator.CreateInstance(null, className).Unwrap()
);
}
}
and then...
public double GetValue(string indicatorName)
{
return _dictionary[indicatorName].Value;
}
Upvotes: 0
Reputation: 262939
If the Indicator
class and its descendants expose a public parameterless constructor, you can use Activator.CreateInstance() to dynamically instantiate a class from its name at runtime:
public class IndicatorCollection
{
public void AddIndicator(string className)
{
_collection.Add((Indicator)
Activator.CreateInstance(null, className).Unwrap());
}
private List<Indicator> _collection = new List<Indicator>();
}
Upvotes: 3
Reputation: 20049
You can use the activator class to instantiate objects based on class name. Assuming the calc_sum
indicator exists in an assembly in the bin directory (or other probing paths), you can get an instance of it:
var myIndicator = Activator.CreateInstance(Type.GetType("calc_sum")) as Indicator;
Upvotes: 0