[英]Implicit operator & generic class
为什么这个C#代码无法编译?
public class X
{ }
public class Xi : X
{
public int I { get; }
public Xi(int i) { I = i; }
public static implicit operator Xi(int i) { return new Xi(i); }
}
public class L<T> : X where T : X
{
public L(params T[] values) { }
}
public static void Main()
{
var test1 = new L<Xi>(1, 2, 3); // OK
var test2 = new L<Xi>(new int[] { 1, 2, 3 }); // Unable to convert int[] into Xi
}
谢谢你的帮助
用你的工作例子:
var test1 = new L<Xi>(1, 2, 3);
C#能够确定params
每个元素都是Xi
类型。 因此,生成的代码相当于
var test1 = new L<Xi>(new Xi[] { 1, 2, 3 });
这里,每个int
都隐式地转换为Xi
,因此你的代码可以工作。 但是 ,使用此代码:
var test2 = new L<Xi>(new int[] { 1, 2, 3 });
你明确地传递了一个int[]
而不是一个Xi[]
。 正如Wazner在评论中指出的那样,数组不是隐式(或明确地,在这种情况下)可转换的。
虽然新实例Xi
可以与初始化int
值,的阵列int
不能被初始化为数组Xi
。
//initializing array of Xi, so for each value constructor of Xi called
Xi[] a = new Xi[] { 1, 2, 3 }; //works
//array of int is not array of Xi
Xi[] b = new int[] { 1, 2, 3 }; //fails
//1, 2, 3 are integers and anonymous array initializes as int[]
Xi[] c = new[] { 1, 2, 3 }; //fails
数组协方差仅适用于引用类型和继承层次结构:
Xi[] a = new Xi[] { 1, 2, 3 };
object[] b = a; //works good
int
不是引用类型, int
不从Xi
继承,它只能转换为Xi
。
public L(params T[] values) { }
public L(IEnumerable<T> values) { }
如果我们定义类似T
的类型,我们应该给出一个合适的type
作为参数。 写Xi
可以而不是int
。
var test2 = new L<Xi>(new Xi[] { 1, 2, 3 });
你已经为int
=> Xi
定义了一个转换器但这没有给你一个从int[]
到Xi[]
的转换器
var test3 = new L<Xi>(new Xi[] { 1, 2, 3 });
因为每个int
被转换为Xi
s然后Xi []被传递到ctor,所以这是有效的。
问题是array
Cast:
你的代码是:
public L(params T[] values) { }
你的电话是:
var test1 = new L<Xi>(1, 2, 3); // OK
1,2,3可以转换为int
因为Xi(int i)
。
另一方面:
var test2 = new L<Xi>(new int[] { 1, 2, 3 });
是一个int
Array
,所以你可以解决几种形式:
L<T>
添加新参数 public L(params int[] values) { }
Xi
,这个表单需要其他array
属性,例如: public class Xi : X
{
public int I { get; }
public int[] Other { get; }
public Xi(int i) { I = i; }
public Xi(int[] i) { Other = i; }
public static implicit operator Xi(int i) { return new Xi(i); }
}
您需要将方法定义放入类/结构定义中。 方法定义不能出现在那些之外。
public class X
{ }
public class Xi : X
{
public int I { get; }
public Xi(int i) { I = i; }
public static implicit operator Xi(int i) { return new Xi(i); }
}
public class L<T> : X where T : X
{
public L(params T[] values) { }
public static void Main()
{
var test1 = new L<Xi>(1, 2, 3); // OK
var test2 = new L<Xi>(new int[] { 1, 2, 3 }); // Unable to convert int[] into Xi
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.