在通用c#类中链接隐式运算符
对于以下通用c#类,我想将T转换为K:
public abstract class ValueType : IValueType where K : ValueType,new() { public abstract T Value { get; set; } public static implicit operator ValueType(T val) { K k = new K(); k.Value = val; return k; } }
如果我要实现直接运算符implicit operator K(T val)
,则会导致编译时错误(CS0556)。
我以为我可以尝试链接隐式运算符:
public static implicit operator K(ValueType vt){ return (K)val; }
但是下面的例子仍然抱怨它无法转换:
public class Test : ValueType { public override int Value{ get; set; } } Test t = 6; //complains it's unable to be converted Console.WriteLine(t.Value);
如果可能的话,我真的想避免明确投射。
这个问题延伸到我之前提出的另一个问题 。
实现自己的隐式转换逻辑的规则非常严格,如果你要做这样特别复杂的规则,你应该对规范的6.4.4和10.10.3非常熟悉。
简而言之,您应该知道的一些关键规则是:
- 您定义转换的类型必须出现在用户定义转换的“到”或“从”部分。 你不能创建一个定义从E到F的转换的C类; C必须在某处。
- 永远不可能用你自己的一个替换内置的隐式转换; 例如,当您从C转换为对象时,您无法发生特殊行为。
- 用户定义的隐式转换将与最多两个内置隐式转换“链接”,但不与任何其他用户定义的转换一起使用。 因此,例如,如果您有一个用户定义的从C到D的隐式转换,以及从D到IFoo的内置隐式转换,那么您将获得从C到IFoo的隐式转换。 但是如果D有一个用户定义的隐式转换为E,那么你就不会获得从C到E的隐式转换。
转换不是由编译器链接的,因此解决问题的方法不起作用。
隐式转换在类型检查中非常严格。 如果编译器知道类型,那么您的第一个片段和Test
类就可以工作:
ValueType t = 6; Console.WriteLine(t.Value);
问题是你的ValueType
– 从类型系统的角度来看 – 并不总是一个Test
,因此隐式转换不适用于那里。
Eric Lippert写了一篇关于这种通用自引用的博客文章 – 值得一读!
据我所知,我不认为你可以把演员连在一起,对不起。
我一直在研究如何创建解析器,如果可能的话,必须有一个无限循环来找到从T
到K
的连接。 我不确定C#解析器会尝试这样做,但不幸的是我的钱没有!