2017-03-09 155 views
3

为什么此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 
} 

感谢您的帮助

+2

数组不会隐式铸造。 – Wazner

回答

2

随着你的工作例如:

var test1 = new L<Xi>(1, 2, 3); 

C#是能够确定每个元素paramsXi型。因此,生成的代码就相当于

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在注释中指出的那样,数组并不是隐式地(或在这种情况下是显式的)castable。

0
public L(params T[] values) { } 
public L(IEnumerable<T> values) { } 

如果我们定义一个类型像T我们应该给予适当的type作为参数。写作Xi是好的,而不是int

var test2 = new L<Xi>(new Xi[] { 1, 2, 3 }); 
+1

重载的构造这里没有轴承 - 的代码编译仅第二代码段(明确地构建'Xi'阵列而不是一个'int'阵列)的,因为在'Program' – Rob

-2

您需要将方法定义放入类/结构定义中。方法定义不能出现在这些之外。

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 
    } 
} 
+0

显然它可以被嵌套类或简单地不同部分的代码。搜索解决方案不是问题。您的代码显然与作者的意图相冲突。 –

0

您已经定义了一个转换器,用于int =>Xi但是这不会给你从int[]一个转换器Xi[]

var test3 = new L<Xi>(new Xi[] { 1, 2, 3 }); 

作品,因为每个int S的转换为Xi秒,然后西[]被传入了Ctor。

0

的问题是array演员:

你的代码是:

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 }); 

intArray,这样你就可以解决这个问题的几种形式:

  • 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); } 
} 
2

虽然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 

Array covariance仅适用于引用类型和继承层次结构:

Xi[] a = new Xi[] { 1, 2, 3 }; 
object[] b = a; //works good 

int不引用类型和int不继承Xi,它只能铸造到Xi