繁体   English   中英

隐式运算符和泛型类

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM