如何解决 T 表示"there is an implicit conversion to T"时缺少的类型约束



我有一个自己的类,我需要使用一堆无法修改的其他类。我已经编写了从我自己的类型到其他类型的隐式转换:

public class MyClass
{
public static implicit operator YourClass(MyClass m) => new YourClass();
public static implicit operator HisClass(MyClass m) => new HisClass();
}

(事实上,所有班级都有成员,但为了简洁起见,我在这里省略了他们。(

现在我可以这样做了:

var mine = new MyClass();
YourClass yours = mine; // implicit conversion takes place

到目前为止,一切都很好。

现在我想写一个从MyType的某个泛型类(我不能修改(实例到上述任何其他类的转换方法,这样我就可以做到:

var listOfMine = new List<MyClass>();
List<YourClass> listOfYours = Convert<YourClass>(listOfMine);

(实际上,所讨论的通用类不是List。(

我喜欢这样写:

public static List<T> Convert<T>(List<MyClass> listOfMine)
where T : MyClass_has_implicit_conversion_to
{
List<T> listOfT = new List<T>();
foreach (var mine in listOfMine)
listOfT.Add(mine); // implicit conversion takes place
return listOfT;
}

,即告诉编译器:T可以是任何存在从MyClassT的隐式转换的类。

但由于不存在这样的类型约束,我无法告诉编译器从MyClassT的转换是合法的。所以它抱怨道:

编译器错误CS1503:参数"mine"无法从MyClass转换为T.

那么我该怎么办

我知道我可以通过来安抚编译器

listOfT.Add((T)(object)mine);

,但随后我得到了一个运行时错误——在这种情况下,我的隐式转换从未被调用。


如果我需要以不同的方式进行转换(即显式转换,如ToYourClass等方法(,我可以接受。

但是我需要Convert<T>方法之外的转换,这样,如果我创建了几个这样的Convert<T>方法(例如,一个用于List<T>,一个针对T[],一个面向Tuple<int,T>,…(,我就不需要重复自己

Charles Mager的评论

您的convert方法无法完成,因为编译器不知道这两种类型之间的任何关系。因此,您需要指定一个函数来在它们之间进行转换。

给了我以下想法:

public static List<T> Convert<T>(List<MyClass> listOfMine, Func<MyClass, T> Convert)
{
List<T> listOfT = new List<T>();
foreach (var mine in listOfMine)
listOfT.Add(Convert(mine)); // manual conversion done here
return listOfT;
}

没关系,我可以接受。

用法:

var listOfMine = new List<MyClass>();
List<YourClass> listOfYours = Convert<YourClass>(listOfMine, x => x);

CCD_ 14将是更明确的,但不是必需的,因为我定义了隐式转换。我也可以定义和使用任何Func<MyClass, YourClass>/Func<MyClass, HisClass>,而不是隐式或显式转换。

mine转换为dynamic也是一个不错的主意(感谢Charlieface(,但由于缺少编译器检查,这是错误的来源,所以如果有其他方法,我希望避免它。

相关内容

  • 没有找到相关文章

最新更新