c#接口 - 隐式转换错误?

时间:2012-12-13 18:17:24

标签: c# interface

如果我有这个界面:

public interface IFoo : IDisposable
{ 
    int PropA {get; set;}
    int PropB {get; set;}
}

一堂课:

public class Foo : IFoo
{
    public int PropA {get; set;}
    public int PropB {get; set;}

    public void Dispose()
    {
        Dispose();
        GC.SuppressFinalize(this);
    }
}

如果没有“无法隐式转换”错误,这不应该有效吗?

    private Context context = new Context();
    private GenericRepository<IFoo> FooRepo;

    public GenericRepository<IFoo> Article
    {
        get
        {
            if (this.FooRepo == null)
            {
                this.FooRepo = new GenericRepository<Foo>(context);
            }
            return FooRepo;
        }
    }

我以为自己做对了,这样做的正确方法是什么?

2 个答案:

答案 0 :(得分:3)

您尝试执行的操作(将GenericRepository<Foo>引用分配给GenericRepository<IFoo>类型的字段)只有在GenericRepository<T>的通用类型参数中为covariant时才有效。为此,GenericRepository<>将被定义为:

public class GenericRepository<out T> {...} //note the "out" modifier. 

然后这个任务就可以了:

this.FooRepo = new GenericRepository<IFoo>(context);

然而,无效,因为协方差仅限于接口代理。因此,为了在该限制内发挥作用,您可以定义协变IGenericRepository<T>接口并使用接口而不是类:

public interface IGenericRepository<out T> {}
public class GenericRepository<T> : IGenericRepository<T> { }

private Context context = new Context();
private IGenericRepository<IFoo> FooRepo;

public IGenericRepository<IFoo> Article
{
    get
    {
        if (this.FooRepo == null)
        {
            this.FooRepo = new GenericRepository<Foo>(context);
        }
        return FooRepo;
    }
}

或者,如果GenericRepository<T>实施IEnumerable,您可以使用Enumerable.Cast<T>方法:

public IGenericRepository<IFoo> Article
{
    get
    {
        if (this.FooRepo == null)
        {
            this.FooRepo = new GenericRepository<Foo>(context).Cast<IFoo>();
        }
        return FooRepo;
    }
}

答案 1 :(得分:1)

您正在尝试将上下文隐式转换为Foo而不是它的接口。还有,Context是否实现了IFoo?如果是,这应该有效。

试试这个:

private Context context = new Context();
private GenericRepository<IFoo> FooRepo;

public GenericRepository<IFoo> Article
{
    get
    {
        if (this.FooRepo == null)
        {
            this.FooRepo = new GenericRepository<IFoo>(context);
        }
        return FooRepo;
    }
}