I have a class Company that holds a list of different IFactory<IPart>; e.g. an EngineFactory.
public class Company
{
private Dictionary<Type, IFactory<IPart>> _factories;
public Company()
{
_factories = new Dictionary<Type, IFactory<IPart>>();
_factories[typeof (Engine)] = new EngineFactory();
}
public void SendOrderIntakeToFactory(IPart part)
{
}
}
The EngineFactory looks like this:
public class EngineFactory : IFactory<Engine>
{
public void Produce(Engine part)
{
}
}
And the IFactory interface:
public interface IFactory<T> where T : IPart
{
void Produce(T part);
}
This will result in a compiler error:
Cannot implicitly convert type 'EngineFactory' to 'IFactory'. An explicit conversion exists (are you missing a cast?)
on this line: _factories[typeof (Engine)] = new EngineFactory();
Ok that makes sense to me, without specifying the variance this will never work. So I tried to add the out keyword to the generic type T, but that will force me to remove the T as method parameter (because it's not allowed to use <out T> as input parameter):
public interface IFactory<out T> where T : IPart
{
void Produce(IPart part);
}
This clearly breaks my generic design. I am able to produce Wheels at my EngineFactory.
I understand the challenge lies in these two requirements:
Store the factory as IFactory<IPart>
The need for a generic void Produce(T part); implementation in the factories.
Is there any way of achieving this?
You can mark generic type parameter as covariant if it used only as return type of methods. Change Produce method to return part and all will work
public interface IFactory<out T> where T : IPart
{
T Produce();
}
You can't use covariant type parameter if it is used as method parameter.
BTW it's really strange factory which accepts objects instead of creating them.
UPDATE you can use runtime type definition with dynamic:
public class Company
{
private Dictionary<Type, dynamic> _factories;
public Company()
{
_factories = new Dictionary<Type, dynamic>();
_factories[typeof(Engine)] = new EngineFactory();
}
public void SendOrderIntakeToFactory(IPart part)
{
_factories[part.GetType()].Produce((dynamic)part);
}
}
When you will call
company.SendOrderIntakeToFactory(new Engine());
Then EngineFactory will be selected and it's Produce method will be called with parameter of runtime type Engine.
I think you could loosen up the dictionary a bit. Consider the following "factory container":
public class Factories
{
private Dictionary<Type, object> _factories;
public Factories()
{
_factories = new Dictionary<Type, object>();
_factories[typeof (Engine)] = new EngineFactory();
}
public IFactory<TPart> GetFactory<TPart>() where TPart:IPart
{
//TODO: add check whether typeof(TPart) exist in the dictionary
return (IFactory<TPart>)_factories[typeof(TPart)];
}
}
This implementation would allow you to do the following:
var factories = new Factories();
var engineFactory = factories.GetFactory<Engine>();
var engine = new Engine();
engineFactory.Produce(engine);
What you are specifically trying to do (mixing covariance and contra-variance) is a rabbit hole. The only solution is NOT to mix variance like this; Move to run-time type checking when you feel the need to mix variance.
[Updated] This would deal with both concerns (strongly typed and flexible location)
interface IPart{}
class Engine : IPart{}
interface IMachine
{
void Produce(IPart part);
Type Type { get; }
}
interface IGenericMachine<in TPart> : IMachine
{
void Produce(TPart with);
}
class EngineMachine : IGenericMachine<Engine>
{
public void Produce(Engine with)
{
}
public void Produce(IPart part)
{
if (part.GetType() != typeof(Engine))
throw new ArgumentException("part must be an Engine");
}
public Type Type { get { return typeof (Engine); } }
}
internal class MachineLocator
{
public Dictionary<Type, IMachine> Machines;
public IGenericMachine<TPart> GetMachine<TPart>()
{
return Machines
.Select(x => x.Value)
.OfType<IGenericMachine<TPart>>()
.Single();
}
public IMachine GetMachine(Type type)
{
return Machines
.Where(x => x.Value.Type == type)
.Select(x=>x.Value)
.Single();
}
}
class Program
{
static public void Main()
{
var locator = new MachineLocator();
locator.Machines.Add(typeof(EngineMachine), new EngineMachine());
var machineKnown = locator.GetMachine<Engine>();
var machineUnknown = locator.GetMachine(typeof(Engine));
machineUnknown.Produce(new Engine());
}
}
When all is said and done; have a look at Inversion of Control as a better design pattern for your program in general. Basically classes don't look for stuff, they get given it.
Related
I have abstract base class like:
public abstract class CacheValueProviderBase<T> where T : ICacheItem
{
protected ConcurrentDictionary<int,T> dataList = new ConcurrentDictionary<int, T>();
public virtual void Add(T model){ // add code }
public virtual bool Remove(int id){ //remove code }
public abstract string getName();
public abstract void UpdateForceFromDataBase();
public abstract void UpdateForceFromCacheServer();
public virtual bool allowForUpdater
{
get
{
return true;
}
}
public virtual bool beforeUpdate()
{
return true;
}
}
I have multiple derived classes from this abstract class. The Slider_CacheValueProvider class below is used as an example.
public class Slider_CacheValueProvider : CacheValueProviderBase<Cache_Home_Slider_Model>
{
public override string getName()
{
return "Slider_Cache";
}
public override void UpdateForceFromCacheServer()
{ // updating from cache server
}
public override void UpdateForceFromDataBase()
{ // updating from database
}
}
Slider cache model:
public class Cache_Home_Slider_Model : ICacheItemID
{
public int ID { get; set; }
public string SlideImage { get; set; }
public string Link { get; set; }
}
All cache models depends ID property and implement this interface just for easy crup operation:
public interface ICacheItemID
{
int ID { get; set; }
}
Info: My caching mechanism has 2 steps. The first step is an internal cache. The second step is an external cache server.
I have cache updater. It is updating caches periodically which depends abstract class 'allowForUpdater' property. Firstly, I found all derived classes with this:
public static List<Type> CacheTypeList()
{
var type = typeof(CacheValueProviderBase<>);
return Assembly.GetExecutingAssembly().GetTypes().Where(i => !i.IsAbstract && !i.IsInterface &&
i.BaseType != null && i.BaseType.IsGenericType && i.BaseType.GetGenericTypeDefinition() == type
).ToList();
}
And iterating like this:
foreach (var item in CacheTypeList())
{
var cache= getCache(item);
if(cache.allowForUpdater && cache.beforeUpdate())
{
cache.UpdateForceFromCacheServer();
}
}
And the getCache method:
public static CacheValueProviderBase<ICacheItem> getCache(Type type)
{
var val = storeList.Find(i => i.Key == type).Value;
return (CacheValueProviderBase<ICacheItem>)val;
}
storeList is static list and include Slider_CacheValueProvider global on app.
The problem is the getCache method. When I try to cast it, I receive an exception. 'Unable to cast object of type ...' . Slider_CacheValueProvider inherited from base and slider model implement from ICacheItem. What is the problem? Why can't I cast?
Update 1:
Using 'out' keyword to abstract class, getting this error:
'Invalid variance modifier. Only interface and delegate type parameters can be specified as variant'.
So i change the abstract class with interface. Interface is :
public interface ICacheProvider<T> where T : ICacheItemID
{
DateTime LastModifiedTime { get; set; }
void Add(T model);
bool Remove(int id);
bool Update(T model);
T Where(Func<T, bool> expression);
void Clear();
int Count(int id);
IEnumerable<T> GetList();
void AddList(IEnumerable<T> model);
void RemoveList(IEnumerable<int> model);
void RemoveByFunc(Func<KeyValuePair<int, T>, bool> expression);
IEnumerable<T> WhereList(Func<T, bool> expression);
string getName();
void UpdateForceFromDataBase(bool updateCache = true);
void UpdateForceFromCacheServer();
bool allowForUpdater { get; }
bool beforeUpdate();
}
And current abstract class like this:
public abstract class CacheValueProviderBase<T> : ICacheProvider<T> where T : ICacheItemID
If i change interface to 'out T', getting error on Add,Update,AddList,RemoveByFunc. Error is:
"Invalid variance, The Type parameter 'T' must be contravariantly valid on ICacheProvider.Add(T) (or other method name) 'T' is a covariant. "
Update 2:
I changed my code. I created new interface for updater like this:
public interface ICacheUpdaterImplements
{
string getName();
void UpdateForceFromDataBase();
void UpdateForceFromCacheServer();
bool allowForUpdater();
}
I get this interface like this:
public static ICacheUpdaterImplements getCacheUpdaterImplements(Type type)
{
return (ICacheUpdaterImplements)storeList.Single(i => i.Key == type).Value;
}
And change updater code like this:
foreach (var item in CacheTypeList())
{
var updater= getCacheUpdaterImplements(item);
if(updater.allowForUpdater())
{
updater.UpdateForceFromCacheServer();
}
}
So, I see, I have wrong design. I changed code and resolve problem.
Neither of the answers given so far are correct. They are right that the problem is that your type is not covariant, but wrong in the proposed solution, which is illegal and will not compile.
Your example is very complicated, so let's look at a simpler example. If you have:
class Animal {}
class Giraffe : Animal {}
class Tiger : Animal {}
Then this conversion is legal:
IEnumerable<Giraffe> giraffes = new List<Giraffe>() { new Giraffe() };
IEnumerable<Animal> animals = giraffes;
This is a covariant conversion. A covariant conversion is a conversion where the justification for the conversion is "Giraffe is convertible to animal, therefore a sequence of giraffes is convertible to a sequence of animals". That is, a covariant conversion is one where an existing conversion justifies a more complex generic conversion.
However, this conversion is not legal:
IList<Giraffe> giraffes = new List<Giraffe>() { new Giraffe() };
IList<Animal> animals = giraffes;
Why is this conversion not allowed? Because it can be abused! We can now say
animals.Add(new Tiger());
The list of animals is still a list of giraffes. You cannot add a tiger to a list of giraffes. You can add a tiger to a list of animals. Therefore, "list of giraffes" is not a subtype of "list of animals", even though giraffe is a subtype of animal. IEnumerable<T> allows covariance because there is no way to insert a tiger into a sequence of giraffes. IList<T> does not allow covariance because there is a way to abuse it.
C# allows covariant conversions like the one you want under the following circumstances:
The generic type arguments involved in the covariant conversion -- that is, the stuff in the <> --- must all be reference types. You cannot, say, convert List<int> to IEnumerable<object> even though int is convertible to object. int is not a reference type.
The "outer" generic type that you are converting to must be an interface or a delegate type, not a class or a struct.
The interface or delegate must be declared as supporting covariance, and the compiler must be able to check that the declaration is valid and never produces a situation where you can put a tiger into a box that can only hold giraffes.
I do not know offhand how to redo your complicated logic to make it work the way you want. You might want to go with a less complicated solution that does not rely on generics so much.
Try this implementation, it should get you what you need... Since you are using generics quite extensively this is the way to go - but if I were you I'd give the whole construct of yours a second thought, since I assume you won't be able to call this method (only by using reflection)
public ICacheProvider<T> getCache<T>() where T : ICacheItem
{
var val = storeList.Single(i => i.Key == typeof(T)).Value;
return (ICacheProvider<T>)val;
}
I have got a bit stuck with working out how to pass a data object to its processor class. I have attempted to give a simplified example of the problem below. I'm trying to figure out if there is a type safe way to instantiate the processor using the generic interface?
Cheers,
Charlie
class APieceOfState
{
public string AbitOfData { get; set; }
}
interface IDescribeSomething<in T>
{
void Process(T type) ;
}
class ImplementWhatIsDescribed : IDescribeSomething<APieceOfState>
{
public void Process(APieceOfState type)
{
Console.WriteLine("Processing {0}", type.GetType());
}
}
private static void Main(string[] args)
{
var nextTest = new ImplementWhatIsDescribed();
var newStateObj = new APieceOfState();
nextTest.Process(newStateObj);
// Map processor to data in a dictionary
var dic = new Dictionary<Type, Type>();
var task = new APieceOfState();
var taskProcessor = new ImplementWhatIsDescribed();
dic.Add(task.GetType(), taskProcessor.GetType());
// Lookup processor using data type
Type lookupProcessorType;
dic.TryGetValue(task.GetType(), out lookupProcessorType);
// vvvvvvvvvvv - How can I make this dynamic based on task.GetType() ?
var instance = (IDescribeSomething<APieceOfState>)Activator.CreateInstance(lookupProcessorType);
instance.Process(task);
Console.ReadKey();
}
First option - you can just use dynamic (not strongly typed)
dynamic instance = Activator.CreateInstance(lookupProcessorType);
instance.Process(task);
If you need compile time checks you'll have to go non-generic interface OR generic method that uses generic interface. The reason is IFoo<OneType> and IFoo<OtherType> are not related by inheritance so there is no common static type you can refer to both.
Sample for non-generic interface:
interface IDescribeSomething
{
void Process(SomeBaseType type);
}
IDescribeSomething instance =
(IDescribeSomething)Activator.CreateInstance(lookupProcessorType);
instance.Process(task);
Sample for generic + base similar to IEnumrable<T>. Note that it generally does not solve your problem but at least some other places can have generic code:
interface IDescribeSomething
{
void Process(SomeBaseType type);
}
interface IDescribeSomething<T> : IDescribeSomething
{
void Process(T type);
}
class APieceOfState : SomeBaseType {}
class ImplementWhatIsDescribed : IDescribeSomething<APieceOfState>
{
public void Process(SomeBaseType type)
{
Process((APieceOfState)type);
}
public void Process(APieceOfState type)
{
Console.WriteLine("Processing {0}", type.GetType());
}
}
IDescribeSomething instance =
(IDescribeSomething)Activator.CreateInstance(lookupProcessorType);
instance.Process(task);
// but in this case you can sometime write strongly type one too
// if you got strongly typed version of interface
IDescribeSomething<APieceOfState> p =...
p.Process(task)
Sample of strongly typed generic method
void DoProcess<T>(T task)
{
IDescribeSomething<T> instance =
(IDescribeSomething<T>)Activator.CreateInstance(lookupProcessorType);
instance.Process(task);
}
You can invoke this method by using MakeGenricMethod - How do I use reflection to call a generic method?
Do you want something like this ?
public void Process<T>(T type) where T : ICommon
{
Console.WriteLine("Processing {0}", type.GetType());
}
public interface ICommon
{
}
I've been building a small access rules module for a project where every particular rule is reflected by a generic Rule<TEntity> object. The rule takes a delegate to execute a certain logic.
There is a RulesContext class that provides methods to check access to a certain entity "foo" like this:
rulesContext.CanIRead<Foo>(myFoo);
My intention was to store all rules build during a setup process into one collection. But every approach I tried lead to a dead end.
I thought of something like:
IDictionary<Type, Rule<object>> _rules = new Dictionary<Type, Rule<object>>();
and:
var fooRule = new Rule<Foo>(foo => foo.FullfillsACertainFooCriterion())
_rules.Add(typeof(Foo), fooRule);
The CanIRead implementation would make sure to use the dictionary properly:
public bool CanIRead<TEntity>(TEntity entity)
{
var rule = _rules[typeof(entity)];
return rule.CanIRead(entity);
}
But the compiler does not like this: Rule<Foo> cannot be assigned to a parameter of type Rule<object>. Which kind of makes sense since it would break the contract (which says that I can use the dictionary's methods with any object as parameter which does not hold true for the fooRule which only accepts Foo typed objects. - Liskov principle)
However I cannot think of a way to solve this. How could I store Rule objects with different types in one collection?
Can you do this:
[TestFixture]
public class ContraVariance
{
[Test]
public void TestNameTest()
{
var rules = new List<IRule<object>>(); //object is used just for demo here, probably some interface of yours is better
rules.Add(new Rule<A>());
rules.Add(new Rule<B>());
}
}
public class A { }
public class B { }
public class Rule<TEntity> : IRule<TEntity>
{
}
public interface IRule<out T>
{
}
If not I think you have to have a non-generic IRule or RuleBase (class)
The out keyword int the interface means that T is out only (Covariant) you can read about it here.
I guess that out will be a problem in your case, i suspect that the rules have methods with TEntity passed as arguments.
Instead of using IDictionary<Type, object> which could hold anything (e.g. DateTime) as a value in the dictionary, you could make the values strictly Rule objects
Here
namespace RuleConsole
{
class Program
{
static void Main(string[] args)
{
var context = new RulesContext();
var objA = new A();
var objB = new B();
context.AddRule<A>(new Rule<A>(objA));
context.AddRule<B>(new Rule<B>(objB));
Console.WriteLine(context.CanIRead<A>(objA));
Console.WriteLine(context.CanIRead<B>(objB));
Console.ReadKey();
}
}
public interface IRule { }
public interface IRule<T> : IRule { }
public class Rule<T> : IRule<T>
{
T _entity;
public Rule(T entity)
{
_entity = entity;
}
}
public class A { }
public class B { }
public class RulesContext
{
Dictionary<Type, IRule> _ruleDict= new Dictionary<Type, IRule>();
public void AddRule<TEntity>(Rule<TEntity> rule)
{
_ruleDict.Add(typeof(TEntity), rule);
}
public bool CanIRead<TEntity>(TEntity entity)
{
var rule = (IRule<TEntity>)_ruleDict[typeof(TEntity)];
//CanIRead implementation here
return rule != null;
}
}
}
That's inherently non-type-safe.
What do you want to happen if you write
_rules[typeof(Foor)].CanRead(new Bar());
You need to make a non-generic base class or interface to store in the dictionary.
Well, this is almost embarassing - but I think you've just helped me unblock my brain :-)
If the problem is that IDictionary<Type, Rule<object>> is too specific, IDictionary<Type, object> does the trick:
var fooRule = new Rule<Foo>(foo => foo.FullfillsACertainFooCriterion())
_rules.Add(typeof(Foo), fooRule);
(same as in the question, but compiles this time)
public bool CanIRead<TEntity>(TEntity entity)
{
var rule = (Rule<TEntity>)_rules[typeof(entity)];
return rule.CanIRead(entity);
}
The blocker in my brain was that I was thinking the more generic the type argument within Rule<...> was, the more objects should be allowed in the dictionary, but in this case it is the other way around: The more generic that argument is, the more specific the contract gets.
Take:
IDictionary<Rule<Foo>>
by replacing Rule by its base class object, the dictionary gets more generic. However, by replacing Foo by object, the whole thing actually gets more specialized!
The whole reason for that is that the type argument of Rule is used as an input parameter.
That's an important lesson...
I have a requirement to use a plug in model where I need to allow types of ITask to be created by structuremap but where I only have a string of the type name at runtime. These types need to use Ctor injection to be composed, so I can't build up an existing type.
Also, I don't want to get all types and then query the type name as they could be expensive to construct.
Is there any built in functionality I am missing?
I haven't tried this, but maybe you could use Type.GetType, like...
var task = (ITask)ObjectFactory.GetInstance(Type.GetType("Assembly.Qualified.Name.Of.Type"));
This assumes you know the assembly/namespaces of the types.
see http://msdn.microsoft.com/en-us/library/w3f99sx1.aspx
Another possibility...
In your scanner add this
Scan(x =>
{
x.AddAllTypesOf<ITask>();
}
Then, in some resolver class...
private Dictionary<string, Type> typeLookup;
public ITask GetInstance(string typeName)
{
if (typeLookup == null)
{
typeLookup = new Dictionary<string, Type>();
var tasks = ObjectFactory.GetAllInstances<ITask>();
foreach (var task in tasks)
{
typeLookup.Add(task.GetType().Name, task.GetType());
}
}
return (ITask)ObjectFactory.GetInstance(typeLookup[typeName]);
}
You can use ObjectFactory.GetNamedInstance<IPerson>("Customer");
The recommended approach is to hide this behind a Factory class:
public interface IPersonFactory
{
IPerson GetPersonInstance(string name);
}
public class StructureMapPersonFactory : IPersonFactory
{
public IPerson GetPersonInstance(string name)
{
return ObjectFactory.GetNamedInstance<IPerson>(name);
}
}
Then you could do something like this:
public class SomethingThatNeedsNamedInstance
{
IPersonFactory _factory;
IPerson _personInstance;
public SomethingThatNeedsNamedInstance(IPersonFactory factory)
{
this._factory = factory; // regular DI greedy constructor, setup in registry.
}
public void DoSomething()
{
this._personInstance = _factory.GetPersonInstance("Customer");
_personInstance.CallSomeMethod();
}
}
In my app, I have deal with several different "parameters", which derive from IParameter interface, and also ParamBase abstract base class. I currently have two different parameter types, call them FooParameter and BarParameter, which both derive from ParamBase. Obviously, I can treat them both as IParameters when I need to deal with them generically, or detect their specific type when I need to handle their specific functionality.
My question lies in specific FooParameters. I currently have a few specific ones with their own classes which derive from FooParameter, we'll call them FP12, FP13, FP14, etc. These all have certain characteristics, which make me treat them differently in the UI. (Most have names associated with the individual bits, or ranges of bits). Note that these specific, derived FP's have no additional data associated with them, only properties (which refer to the same data in different ways) or methods.
Now, I'd like to keep all of these parameters in a Dictionary<String, IParameter> for easy generic access. The problem is, if I want to refer to a specific one with the special GUI functions, I can't write:
FP12 fp12 = (FP12)paramList["FP12"] because you can't downcast to a derived type (rightfully so). But in my case, I didn't add any data, so the cast would theoretically work.
What type of programming model should I be using instead? Thanks!
There's nothing really wrong with this approach, except for maybe storing the parameters in a dictionary. What is the purpose of doing that? Especially if you key them on their class name.
I would just use a List<IParameter> and have a control go through the collection and pick the right subclass out of there.
m_Parameters = new List<IParameter>();
//This control needs FP12
foreach(var param in Parameters) {
var fp12 = param as FP12;
if (fp12 != null) {
//do something with the param.
break;
}
}
After writing the above I think I finally understand what you are trying to do. If you want to perform an operation that is available on FP12 on any subclass of FooParameter then you need to take that operation out of FooParameter altogether. Since your parameter is data and that data is the same across different subclasses of FooParameter, it makes sense to only have one implementation of FooParameter ("data" class) and multiple "operation" classes.
//The one implementation of IParameter for all FooParameters
public class FooParameter : IParameter {
string Data1 {get;set;}
}
//base class for Foo Operation, only stores FooParameter
public class FooOperationBase {
protected readonly FooParameter m_Param;
public FooOperationBase (FooParameter param) {
m_Param = param;
}
}
//specific operations on FooParameter go in this class
public class FooOperation12 : FooOperationBase {
public FooOperation12(FooParameter param) : base(param) {}
public void DoSomeOperation() {
return m_Param.Data1 + " transformed";
}
}
If paramList["FP12"] is a FP12, that cast will work. Of course, if it's not it will throw a InvalidCastException. You could also use as, if you're not sure what type the object will be.
Whether this is an ideal design is a separate issue. Ideally, you want to prefer polymorphism, meaning the subclass of FooParameter knows to use its new special functions internally, and the outside code doesn't have to cast, or use as or is.
I'm not 100% sure where you're coming from with this question, but you could do something like this:
class Program
{
static void Main(string[] args)
{
var paramList = new List<IParameter>();
paramList.Add(new FooParameter());
paramList.Add(new BarParameter());
paramList.Add(new F1());
paramList.Add(new F2());
foreach (var p in paramList)
{
p.DoCommonOperation();
DoSpecificOperation(p);
}
Console.ReadKey();
}
private static void DoSpecificOperation(IParameter p)
{
if (p is F1)
{
(p as F1).F1Method();
}
else if (p is F2)
{
(p as F2).F2Method();
}
}
interface IParameter
{
void DoCommonOperation();
}
abstract class ParamBase : IParameter
{
public virtual void DoCommonOperation()
{
Console.WriteLine("ParamBase");
}
}
class FooParameter : ParamBase
{
public override void DoCommonOperation()
{
Console.WriteLine("FooParameter");
}
}
class BarParameter : ParamBase
{
public override void DoCommonOperation()
{
Console.WriteLine("BarParameter");
}
}
class F1 : FooParameter
{
public override void DoCommonOperation()
{
Console.WriteLine("F1");
}
public void F1Method()
{
Console.WriteLine("F1.F1Method");
}
}
class F2 : FooParameter
{
public override void DoCommonOperation()
{
Console.WriteLine("F2");
}
public void F2Method()
{
Console.WriteLine("F2.F2Method");
}
}
}
Essentially you have a method in the class that controls the list of IParameter objects that knows how to call the specific implementations, and uses is/as to do so.
Just for sanity's sake, why not use Dictionary<Type, IParameter>? With a little generics, you could do this:
public interface IParameter { }
public class FP12 : IParameter { public string fieldFP12 { get; set; } }
public class FP11 : IParameter { public string fieldFP11 { get; set; } }
public static class DictionaryHelper
{
public static T GetParameter<T>(this Dictionary<System.Type,
IParameter> target) where T : IParameter
{
return (T)target[typeof(T)];
}
}
Sample program and output:
class Program
{
static void Main()
{
Dictionary<Type, IParameter> parameters =
new Dictionary<Type, IParameter>();
parameters.Add(typeof(FP12), new FP12 { fieldFP12 = "This is FP12" });
parameters.Add(typeof(FP11), new FP11 { fieldFP11 = "This is FP11"});
// THIS IS WHERE YOU GET THE IPARAMETER YOU WANT - THE GENERICS WAY...
var fp12 = parameters.GetParameter<FP12>();
var fp11 = parameters.GetParameter<FP11>();
Console.WriteLine(fp12.fieldFP12);
Console.WriteLine(fp11.fieldFP11);
Console.ReadLine();
}
}
The resulting output:
This is FP12
This is FP11