C# 将泛型类强制转换为接口

C# 将泛型类强制转换为接口,c#,generics,casting,clr,C#,Generics,Casting,Clr,我在将泛型类强制转换到它正在实现的接口时遇到问题 我的代码如下: interface foo { void foobar(); } class bar: foo { public void foobar() { throw new NotImplementedException(); } } 现在我有了我的工厂,它通过接口创建类的实例,主要是一个简单的微核(服务定位器)。我将在这里简化它。通常,它会从configs中查找实现类,工厂将类型设置为

我在将泛型类强制转换到它正在实现的接口时遇到问题

我的代码如下:

interface foo
{
    void foobar();
}

class bar: foo
{
    public void foobar()
    {
        throw new NotImplementedException();
    }
}
现在我有了我的工厂,它通过接口创建类的实例,主要是一个简单的微核(服务定位器)。我将在这里简化它。通常,它会从configs中查找实现类,工厂将类型设置为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;
    }
}
公共静态类工厂
{
公共静态惰性CreateLazyInstance()
{
惰性实例;
类型=类型(条形);
Type lazyType=typeof(懒惰);
Type-tocontract=lazyType.MakeGenericType(类型);
instance=(Lazy)Activator.CreateInstance(toContract);
返回实例;
}
}
如果在以下位置失败:

instance = (Lazy<foo>)Activator.CreateInstance(toContruct);
instance=(Lazy)Activator.CreateInstance(toContract);
并以InvalidCastException声明不可能将类型
Lazy
强制转换为
Lazy

有没有办法告诉CLR此强制转换将起作用或解决此问题?

否-是不变的-因此,例如,
惰性
不是
惰性
。(正如注释中指出的,它不能在
t
中声明为协变,因为它是一个类,而不是一个接口或委托。)

但是,您可以很容易地将一个转换为另一个:

static Lazy<TOutput> CreateLazyProxy<TInput, TOutput>
    (Lazy<TInput> input) where TInput : TOutput
{
    return new Lazy<TOutput>(() => input.Value);
}
静态惰性CreateLazyProxy
(惰性输入)其中TInput:TOutput
{
返回新的延迟(()=>input.Value);
}
另外,
Func
是协变的,因此这也适用:

static Lazy<TOutput> CreateLazy<TInput, TOutput>(Func<TInput> func)
    where TInput : TOutput
{
    return new Lazy<TOutput>(func);
}
static Lazy CreateLazy(Func-Func)
TInput的位置:TOutput
{
返回新的Lazy(func);
}

(并不是说你特别需要一个方法——如果你有一个
Func
,直接构造一个
Lazy

一个更简单的方法是将lambda传递给Lazy构造函数。因此,您的代码如下所示:

  public static Lazy<foo> CreateLazyInstance()
  {
     Type type = typeof(bar);
     return new Lazy<foo>(() => (foo)Activator.CreateInstance(type));
  }  
公共静态惰性CreateLazyInstance()
{
类型=类型(条形);
返回新的Lazy(()=>(foo)Activator.CreateInstance(type));
}  

必须执行foo通用参数:new():


它不能;它不是一个接口。@SLaks:您可以添加一个惰性接口,并让当前类实现该接口。@siride:除了
Lazy
是一个BCL类,不能修改之外。@SLaks:oops!知道Jon Skeet犯了类似的错误,我至少可以感到安慰。您的bar类没有实现foo接口。你的代码甚至都没有编译。@Icarus:我想那是无关紧要的。他只是想表明他有一个用bar实现foo的类层次结构。
public static Lazy<foo> CreateLazyInstance() where foo : new()
Type t = typeof(foo);
t.GetConstructor(new type[]{});
return (foo)t.Invoke(new object[]{});