2012-02-03 103 views
3

如何在C#中重新初始化隱式類型變量(var)?C#隱含類型變量重新初始化

  var abc = new Class(); 
      if (a == 1) 
      { 
       abc = new Class1(); 
      } 
      else if (a == 2) 
      { 
       abc = new Class2(); 
      } 
      else if (a == 3) 
      { 
       abc = new Class3(); 
      } 

現在我有上面這樣,我得到一個錯誤。

不能鍵入「1類」隱式轉換爲「類」

+2

你能解釋一下你爲什麼要這麼做?也許對於你的問題有更好的解決方案,但沒有上下文就無法說清楚。 – 2012-02-03 15:12:10

+0

將'var'替換爲'object',但是這會破壞var的目的。 – ja72 2013-06-26 18:10:24

回答

3

你不能,在那種情況下你只能這樣做,如果1類/ 2/3明確地類繼承。

0

你不能這樣做。這只是一種等效寫作方式

Class abc = new Class(); 
if (a == 1) 
{ 
    abc = new Class1(); // fails or requires implicit conversion 
} 

這顯然在一般情況下不起作用。

2

你沒有。隱式初始化由編譯器在指定的點來確定,因此,你的第一行:一旦它確定爲Class型的就不能

Class abc = new Class(); 

所以:

var abc = new Class(); 

等效於改變的不僅僅是明確的聲明。

也許你想要做dynamic打字呢?

7

你不行。 var不能像那樣工作。 var的意思是「看,我懶得輸出這個變量的真實靜態類型名稱,你能爲我解決嗎?」這就是隱式輸入的意思。

因此,在第一行中,編譯器決定將abc鍵入爲對Class的引用。然後,您稍後嘗試將對Class1的引用分配給abc。當然,這是不可能的,除非有從Class1Class的轉換。

緊張,你的代碼是因爲如果你寫

Class abc = new Class(); 
if (a == 1) { 
    abc = new Class1(); 
} 
else if (a == 2) { 
    abc = new Class2(); 
} 
else if (a == 3) { 
    abc = new Class3(); 
} 

事實上,它的語義相同。但現在你的錯誤是顯而易見的。您正在嘗試分配Class1abc的引用,但abc無法接受,除非存在從Class1Class的隱式轉換。

7

VAR隱式類型仍然是靜態類型

var abc = new Class(); 

完全等同於

Class abc = new Class(); 

除非的Class1,Class2中和Class3的擴展類,你不能將它們分配給ABC。

+1

或者存在從「Class1」等到「Class」的隱式轉換。 – jason 2012-02-03 15:23:47

+0

@Jason好點,我的措辭有些不準確。在轉換的情況下,它仍然是由轉換創建並存儲在abc中的類(或可能是派生類)。 – 2012-02-03 15:31:28

0

一個隱式類型變量仍然尊重多態性 - 讓你的推斷變量是Class類型:

Class abc = new Class(); 

由於Class1不(大概)從Class繼承,這是無效的重新分配。如果要將推斷變量鍵入限制較少的基本類型(例如對象),則可以寫出聲明(首選)或右側,以便編譯器推斷出不同的類型:

object abc = new Class(); // Preferred 
var abc = (object)new Class(); // Works 
2

你不能做你所問的,但你可以做到這一點。

 object abc = new Class(); 
     if (a == 1) 
     { 
      abc = new Class1(); 
     } 
     else if (a == 2) 
     { 
      abc = new Class2(); 
     } 
     else if (a == 3) 
     { 
      abc = new Class3(); 
     } 

雖然這並沒有提供很大的價值。如果所有的類都從一個通用的類或接口繼承而來,那麼你需要做的工作可能就是你要做的。因此,例如

 Animal abc = new Animal(); 
     if (a == 1) 
     { 
      abc = new Dog(); 
     } 
     else if (a == 2) 
     { 
      abc = new Cat(); 
     } 
     else if (a == 3) 
     { 
      abc = new Person(); 
     } 
     abc.sleep() 

睡眠會然後調用爲其正確的函數曾經鍵入重音了。

2

你可以做到這一點var abc = new Class();,因爲var是一種通用類型,當你這樣做時,你正在做Class abc = new Class();。問題是當你試圖做re-initalize。但是你錯了,在你做abc = new Class1();之後,你並沒有重新初始化abc,但是你傳遞的是Class類型的新對象的pointer。所以編譯器說你不能做這個轉換,因爲abc的類型是Class

但是你可以使用object,作爲所述馬克Backett,因爲類型object是所有類的基類

另外一個解決辦法是這樣的:

int a = Convert.ToInt(Console.ReadLine()); 

var abc = new Class(); 

if (a == 1) 
    abc = new Class1(); 
else if (a == 2) 
    abc = new Class2(); 
else if (a == 3) 
    abc = new Class3(); 

public class Class { ... } 
public class Class1:Class{ ... } 
public class Class2:Class1{ ... } 
public class Class3:Class2{ ... } 
+1

+1:它重申其他答案已經說過的內容,但我更喜歡這裏的例子。我建議不要使用類的繼承來使用接口的實現來鏈接類。 'IMyInterface abc = new Class();'...'public class Class:IMyInterface {...}'。 – 2012-02-03 16:14:09

+0

@JoelEltherton是的,我喜歡這個想法,也許在這種情況下,它可能比使用類的繼承更好。謝謝。 – 2012-02-03 16:30:45

-1

有點遲到了,但爲什麼不:

if (a == 1) 
{ 
    var abc = new Class1(); 
} 
else if (a == 2) 
{ 
    var abc = new Class2(); 
} 
else if (a == 3) 
{ 
    var abc = new Class3(); 
} 
else 
{ 
    var abc = new Class(); 
} 
+0

因爲你發佈的代碼是無用的;你永遠不能訪問變量。推測該變量是在OP示例中的if/else語句之後使用的。 – Servy 2013-06-26 18:07:38