投泛型类的接口 [英] Cast generic class to interface

查看:179
本文介绍了投泛型类的接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有铸造泛型类是实现接口的问题。



我的代码是这样的:

 接口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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆