c# - 你能用隐式转换满足通用约束吗?

标签 c# generics implicit-conversion

给定这些类型:

class A { }
class B
{
    public static implicit operator A(B me)
    {
        return new A();
    }
}

class Test<T> where T : A { }

我试过了

var b = new Test<B>();

并预计它会失败,但它确实失败了。但是报错信息是

The type 'B' cannot be used as type parameter 'T' in the generic type or method 'Test'. There is no implicit reference conversion from 'B' to 'A'.

但是从 B 到 A 的隐式引用转换。这只是一条奇怪的消息吗? 不是隐式引用转换正如亚当罗宾逊的回答所示。消息是正确的。

请注意 MSDN says:

where T : (base class name) - The type argument must be or derive from the specified base class.

这解释了为什么它是不允许的,因为 B 不是从 A 派生的

最佳答案

不,你想做的事是不可能的。隐式引用 转换与隐式类型 转换不同。您的代码定义了一个隐式类型转换,您可以在其中执行以下操作:

B foo = new B();
A bar = foo;

但是请注意,foobar 现在包含不同的引用。隐式类型转换创建了 A实例,它应该(按照惯例)在逻辑上等同于 foo。但关键是它是一个不同的引用。

引用 转换将是引用本身不改变的地方,这意味着所讨论的类型必须继承自(对于类)或实现(对于接口(interface))所讨论的类型。如果我这样做:

class A { }
class B : A { }

然后我上面的代码现在将在 foobar 中包含相同的引用。这就是隐式引用转换的含义。相反,显式引用转换将是向下转换,如下所示:

A foo = new B();
B bar = (B)foo;

同样,引用是相同的,但转换是明确的。

因此,简而言之,MSDN 文档更清晰但不够精确。

关于c# - 你能用隐式转换满足通用约束吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8172112/

相关文章:

java - 从java中的枚举列表中删除一个元素

c# - 如何处理通用返回 T 的异常

c++ - CRTP 中 shared_ptr 的隐式向下转换

c++ - 在表达式 bool << integer 中,bool 是提升为 int,还是提升为与整数相同的类型?

Scala:如何使用隐式参数定义匿名函数?

c# - WAN 上的 TCP 和 UDP 套接字服务器

c# - 内部 StackPanel 不可见

c# - 我应该为 64 位 Windows 操作系统构建 x86 还是 x64 应用程序?

c# - IErrorHandler 在 HTTP 状态代码为 401 Unauthorized 时返回错误的消息正文

c# - 如何连接两个类型为 List<KeyValuePair<string,string>> 的 C# 列表。我有一些重复值,我需要这些重复值