[英]Chaining implicit operators in generic c# classes
For the following generic c# class, I'd like to convert T to K:对于以下通用 c# class,我想将 T 转换为 K:
public abstract class ValueType<T,K> : IValueType<T> where K : ValueType<T,K>,new()
{
public abstract T Value { get; set; }
public static implicit operator ValueType<T,K>(T val)
{
K k = new K();
k.Value = val;
return k;
}
}
If I were to implement a direct operator implicit operator K(T val)
it would result in a compile-time error (CS0556).如果我要实现直接运算符
implicit operator K(T val)
,它将导致编译时错误 (CS0556)。
I thought I could try chaining implicit operators:我想我可以尝试链接隐式运算符:
public static implicit operator K(ValueType<T,K> vt){
return (K)val;
}
but the following example still complains that it can't be converted:但是下面的例子仍然抱怨无法转换:
public class Test : ValueType<int, Test>
{
public override int Value{ get; set; }
}
Test t = 6; //complains it's unable to be converted
Console.WriteLine(t.Value);
I really want to avoid explicitly casting if possible.如果可能的话,我真的想避免显式转换。
This question extends upon another SO question I've previously raised.这个问题延伸到我之前提出的另一个 SO 问题。
The rules for implementing your own implicit conversion logic are quite strict and you should probably become very familiar with sections 6.4.4 and 10.10.3 of the specification if you're going to do particularly complicated ones like this. 实现自己的隐式转换逻辑的规则非常严格,如果您要进行此类特别复杂的操作,则应该熟悉本规范的6.4.4和10.10.3节。
Briefly, a few key rules you should know are: 简要地说,您应该了解一些关键规则:
Casts are not chained by the compiler, so that way of solving the issue doesn't work. 强制转换未通过编译器链接,因此无法解决问题。
Implicit casts are quite strict in the type checking. 隐式转换在类型检查中非常严格。 Your very first snippet and the
Test
class do work if the compiler knows the type: 如果编译器知道类型,则第一个代码段和
Test
类都可以工作:
ValueType<int, Test> t = 6;
Console.WriteLine(t.Value);
The problem is that your ValueType<int, Test>
- from the type system point of view - is not always a Test
, so that the implicit conversion doesn't apply there. 问题是,从类型系统的角度来看,您的
ValueType<int, Test>
并不总是Test
,因此隐式转换不适用于该类。
Eric Lippert wrote a blog post on this kind of generic self-referencing by the way - worth a read! 埃里克·利珀特(Eric Lippert)撰写了一篇有关这种通用自引用的博客文章 -值得一读!
As far as I know, I don't think that you can chain casts together, sorry about that. 据我所知,我认为您不能将演员表捆绑在一起,对此感到抱歉。
I've been studying how to create parsers, and if this was possible, there would have to be an indefinite loop to find the connection from T
to K
. 我一直在研究如何创建解析器,如果可能的话,必须存在一个不确定的循环才能找到从
T
到K
的连接。 I'm not sure that the C# parser would try doing that, but my money is on no, unfortunately! 我不确定C#解析器是否会尝试这样做,但是不幸的是,我的钱没有用!
Here is what I came up to.这是我想到的。 Not an answer to the OP question, but as far as I look for, from C# rules it is not possible anyway.
不是 OP 问题的答案,但据我所知,从 C# 规则来看,无论如何都是不可能的。 So what I did it to implement the implicit operator in concrete class that rely on the conversion algorithm defined in the abstract class.
所以我做了什么来实现具体 class 中的隐式运算符,它依赖于抽象 class 中定义的转换算法。
My classes:我的课程:
public interface IInjectable<T>
{
T Value { get; set; }
}
internal abstract class Injectable<T,P> : IInjectable<T>
where P : Injectable<T,P>, new()
{
public abstract T Value { get; set; }
public static implicit operator T(Injectable<T,P> injectable) => injectable.Value;
//public static implicit operator Injectable<T,P>(T value) => new P { Value = value };
public static P Convert(T value) => new P { Value = value };
}
internal class InjectableGuid : Injectable<Guid, InjectableGuid>
{
public override Guid Value { get; set; } = Guid.Empty;
public override string ToString() => Value.ToString();
public static implicit operator InjectableGuid(Guid guid) => Convert(guid);
}
Usage:用法:
Guid id = new InjectableGuid();
Console.WriteLine(id.ToString());
Guid newId = Guid.NewGuid();
Console.WriteLine("Guid.ToString() : "+newId.ToString());
InjectableGuid injected = newId;
Console.WriteLine("InjectableGuid.ToString() : "+injected.ToString());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.