投泛型类的接口 [英] Cast generic class to interface
问题描述
我有铸造泛型类是实现接口的问题。
我的代码是这样的:
接口foo的
{
无效foobar的();
}
类酒吧:富
{
公共无效foobar的()
{
抛出新NotImplementedException();
}
}
现在我有我的工厂,创建我的类的实例由接口,大多是一个简单的微内核(服务定位器)。我将在这里简化它。通常情况下它会查找执行类从CONFIGS和工厂采取的类型为T但这不要紧,我有这个问题。
公共静态类工厂
{
公共静态懒<富> CreateLazyInstance()
{
&懒LT;富>实例;
$ B $型B型= typeof运算(巴);
型lazyType = typeof运算(懒惰<>);
型toContruct = lazyType.MakeGenericType(类型);
实例=(懒惰<富>)Activator.CreateInstance(toContruct);
返回实例;
}
}
如果将失败的:
实例=(懒惰<富>)Activator.CreateInstance(toContruct);
和声称与一个InvalidCastException,这是不可能的投类型懒< ;酒吧和GT;
到懒<富方式>
有没有办法告诉在CLR,这将投工作或解决这一问题。
没有 - 的 懒< T>
是的不变的 - 所以懒<串GT;
不是懒<对象>
为例。 (正如在评论中指出,它可能不会在 T宣布为协变
,因为它是一个类,而不是接口或委托。)
不过,你可以转换一个到另一个足够容易:
静态懒< TOutput> CreateLazyProxy< TInput,TOutput>
(懒惰< TInput>输入),其中TInput:TOutput
{
返回新懒人< TOutput>(()=> input.Value);
}
此外, Func键< T>
的是的协变,所以这也可以工作:
静态懒< TOutput> CreateLazy< TInput,TOutput>(Func键< TInput> FUNC)
式TInput:TOutput
{
返回新懒人< TOutput>(FUNC);
}
(不,你特别需要一个方法 - 如果你获得的一个 Func键< TInput>
,只是构建一个懒< TOutput>
直接)<。 / p>
I have a problem with casting a generic class to the interface it is implementing.
My code is like this:
interface foo
{
void foobar();
}
class bar: foo
{
public void foobar()
{
throw new NotImplementedException();
}
}
now I have my factory that creates instances of my classes by the interface, mostly a simple microkernel (service locator). I will simplify it here. Normally it will look up the implementing class from the configs and the factory take the type as T but that doesn't matter for the problem I have.
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;
}
}
If will fail at:
instance = (Lazy<foo>)Activator.CreateInstance(toContruct);
and claim with an InvalidCastException that it is not possible to cast the type Lazy<bar>
to Lazy<foo>
.
Is there any way to tell the CLR that this cast will work or to workaround this problem?
No - Lazy<T>
is invariant - so a Lazy<string>
is not a Lazy<object>
for example. (As pointed out in comments, it couldn't be declared as covariant in T
, as it's a class, not an interface or delegate.)
However, you can convert one to the other easily enough:
static Lazy<TOutput> CreateLazyProxy<TInput, TOutput>
(Lazy<TInput> input) where TInput : TOutput
{
return new Lazy<TOutput>(() => input.Value);
}
Also, Func<T>
is covariant, so this will work too:
static Lazy<TOutput> CreateLazy<TInput, TOutput>(Func<TInput> func)
where TInput : TOutput
{
return new Lazy<TOutput>(func);
}
(Not that you particularly need a method for that - if you've got a Func<TInput>
, just construct a Lazy<TOutput>
directly.)
这篇关于投泛型类的接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!