隐含算子&泛类

时间:2017-03-09 10:56:42

标签: c#

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

感谢您的帮助

6 个答案:

答案 0 :(得分:2)

用你的工作例子:

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在注释中指出的那样,数组不是隐式的(或者在本例中是显式的)可转换的。

答案 1 :(得分:2)

虽然可以使用this.getFullName = function(){ var full = this.fullName || (function(){ var first = firstAndLast.split(' ')[0]; var last = firstAndLast.split(' ')[1]; return first + " " + last; })(); return full; }; 值初始化Xi的新实例,但int的数组无法初始化为int的数组。

Xi

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

//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

答案 2 :(得分: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 });

答案 3 :(得分:0)

您已为int =&gt;定义了转换器Xi但是这不会为您提供从int[]Xi[]

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

有效,因为每个int都转换为Xi s,然后Xi []被传递到ctor。

答案 4 :(得分: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 });

Array的{​​{1}},因此您可以通过多种形式解决此问题:

  • int
  • 中添加新参数

L<T>
  • 重载public L(params int[] values) { } ,此表单需要其他Xi属性,例如:

array

答案 5 :(得分:-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
   }
}