[英]Cast generic class to interface
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.
通常它会从配置中查找实现类,工厂将类型作为 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;
}
}
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>
.并使用 InvalidCastException 声明无法将类型
Lazy<bar>
为Lazy<foo>
。
Is there any way to tell the CLR that this cast will work or to workaround this problem?有什么方法可以告诉 CLR 此演员表可以工作或解决此问题吗?
No - Lazy<T>
is invariant - so a Lazy<string>
is not a Lazy<object>
for example.不 -
Lazy<T>
是不变的- 例如, Lazy<string>
不是Lazy<object>
。 (As pointed out in comments, it couldn't be declared as covariant in T
, as it's a class, not an interface or delegate.) (正如评论中所指出的,它不能在
T
声明为协变,因为它是一个类,而不是接口或委托。)
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:此外,
Func<T>
是协变的,所以这也适用:
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.) (并不是说你特别需要一个方法——如果你有一个
Func<TInput>
,直接构造一个Lazy<TOutput>
。)
An easier way to do this would be to pass in a lambda to the Lazy constructor.一种更简单的方法是将 lambda 传递给 Lazy 构造函数。 So, your code would look like the following:
因此,您的代码如下所示:
public static Lazy<foo> CreateLazyInstance()
{
Type type = typeof(bar);
return new Lazy<foo>(() => (foo)Activator.CreateInstance(type));
}
You must do your foo generic parameter : new():你必须做你的 foo 通用参数:new():
public static Lazy<foo> CreateLazyInstance() where foo : new()
And change your code to find a constructor and call it:并更改您的代码以查找构造函数并调用它:
Type t = typeof(foo);
t.GetConstructor(new type[]{});
return (foo)t.Invoke(new object[]{});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.