2017-03-09 170 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