use*_*923 14 c# generics dictionary
我有一本字典:
private Dictionary<Type, IExample> examples;
Run Code Online (Sandbox Code Playgroud)
我有两个实现接口的类:
public class Example1 : IExample
{
}
public class Example2 : IExample
{
}
Run Code Online (Sandbox Code Playgroud)
我已经创建了一种从字典中获取实例的方法,如果它存在但是我试图找出一种方法来实例化一个新对象(如果它不存在).
public T GetExample<T>() where T : IExample
{
// Return the signal if it exists
if (examples.ContainsKey(typeof(T)))
{
IExample value;
if (!examples.TryGetValue(typeof(T), out value))
{
// unable to get value
}
return (T)value;
}
// Stuck on this line here. How exactly do I instantiate a new example if it doesn't exist.
examples.Add(typeof(T), new );
return default(T);
}
Run Code Online (Sandbox Code Playgroud)
这样的事情可能吗?
Ehs*_*jad 13
您需要在无参数构造函数的泛型方法上添加泛型类型参数约束,然后您可以实例化类型T参数,如new T():
public T GetExample<T>() where T : IExample,class,new()
{
IExample value;
if (examples.TryGetValue(typeof(T), out value))
{
return (T)value;
}
T obj = new T(); // create instance of T and use further down in code it's reference
examples.Add(typeof(T),obj );
return obj ;
}
Run Code Online (Sandbox Code Playgroud)
并且return default(T);不会返回类null的新实例T(引用类型)默认值是null,我怀疑你想在return new T();那里做什么,它会创建一个新对象并将它的引用返回给调用者.
尽管您当然可以创建一个需要默认构造函数的类型约束,但它通常过于拘束:代码的用户可能不愿意将默认构造函数设置为public,或者根本没有默认构造函数.
更灵活的方法需要一个创建缺少对象的委托:
public T GetExample<T>(Func<T> make) where T : IExample, class {
IExample value;
if (examples.TryGetValue(typeof(T), out value)) {
return (T)value;
}
T res = make();
examples.Add(typeof(T), res);
return res;
}
Run Code Online (Sandbox Code Playgroud)
这样,当您需要的对象未缓存在中时,调用者可以控制如何创建新对象examples.您的代码回调"按需",因此对象创建逻辑仍然牢牢地隐藏在调用者的代码中
var e = exampleFactory.GetExample<MyExample>(
() => new MyExample(firstParameter, secondParameter)
);
Run Code Online (Sandbox Code Playgroud)