我在将泛型类转换为它正在实现的接口时遇到问题。
我的代码是这样的:
interface foo
{
void foobar();
}
class bar: foo
{
public void foobar()
{
throw new NotImplementedException();
}
}
现在我的工厂通过接口创建类的实例,主要是一个简单的微内核(服务定位器)。我在这里将其简化。通常它会从配置中查找实现类,并且工厂将类型视为 T 但这对于我遇到的问题并不重要。
public static class Factory
{
public static Lazy<foo> CreateLazyInstance()
{
Lazy<foo> instance;
Type type = typeof(bar);
Type lazyType = typeof(Lazy<>);
Type toContruct = lazyType.MakeGenericType(type);
instance = (Lazy<foo>)Activator.CreateInstance(toContruct);
return instance;
}
}
如果将失败于:
instance = (Lazy<foo>)Activator.CreateInstance(toContruct);
并用 InvalidCastException 声明不可能强制转换类型Lazy<bar>
to Lazy<foo>
.
有什么方法可以告诉 CLR 这个转换可以工作或者解决这个问题吗?
No - Lazy<T> http://msdn.microsoft.com/en-us/library/dd642331.aspx is 不变的 - so a Lazy<string>
不是一个Lazy<object>
例如。 (正如评论中指出的,它不能被声明为协变T
,因为它是一个类,而不是接口或委托。)
但是,您可以轻松地将一种转换为另一种:
static Lazy<TOutput> CreateLazyProxy<TInput, TOutput>
(Lazy<TInput> input) where TInput : TOutput
{
return new Lazy<TOutput>(() => input.Value);
}
Also, Func<T>
is协变,所以这也可以工作:
static Lazy<TOutput> CreateLazy<TInput, TOutput>(Func<TInput> func)
where TInput : TOutput
{
return new Lazy<TOutput>(func);
}
(并不是说您特别需要一种方法 - 如果您已经got a Func<TInput>
,只需构造一个Lazy<TOutput>
直接地。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)