接口、泛型和隐式操作

3
假设我有以下类型:
public class Foo<T>
{
    public Foo(T value)
    {
         Value = value;
    }

    public T Value {get;set;}

    public static implicit operator Foo<T>(T t)
    {
        return new Foo<T>(t);
    }
}

public interface IBar
{
}

public class Bar : IBar
{
}

为什么我不能写这个?
Foo<IBar> foo = (IBar)new Bar();

但是仍然允许写这个吗?
Foo<Bar> foo = new Bar();

我遇到了这个错误:
无法隐式转换类型IBar为Foo。存在一个显式转换(你是否缺少一次强制类型转换?)。
我知道在接口中不能使用隐式操作符,但为什么在接口作为泛型参数时也不能使用它们?

1
从接口进行强制转换是内置的转换。您无法覆盖内置转换。 - user4003407
它可以在没有(IBar)的情况下工作。 - IS4
1
个人而言,我会尽量避免这样做——这段代码非常令人困惑。为什么不添加一个扩展方法呢?public static Foo<T> ToFoo<T>(this T t) - Jon Skeet
我在考虑开发自己的类来替换System.Lazy,因为它在值的转换上有些烦人。所以我添加了几个隐式操作符,用于从我的懒加载类转换到其他类型,反之亦然。一切都很完美,直到我尝试将接口用作泛型参数。 - xBodro
2个回答

0

如果您删除泛型参数,只保留operator Foo(IBar t),它会引发CS0552

您不能创建与接口之间的用户定义转换。如果需要转换例程,请通过将接口设置为类或从接口派生类来解决此错误。

因此,接口之间的用户定义转换是不允许的。这与您收到的第一个错误有关:

无法隐式地将类型IBar转换为Foo< IBar >。存在显式转换(是否缺少强制转换?)

如果已经存在显式转换(现在从IBarFoo),则不能有隐式转换。

因此,您不能重载与接口之间的用户定义转换,因为该类型已经定义了内置转换(尽管是显式转换)。


我知道我不能隐式地转换一个接口,但是泛型类仍然是一个类,即使泛型参数是一个接口。 - xBodro
@xBodro 这是事实,不过(IBar)new Bar() 是一个接口,在使用用户定义运算符时无法转换。 - IS4

0

我不是完全确定我要说什么。

这是因为它不接受转换为接口的东西(因为无法从类创建对象),但会接受实现该接口的所有内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接