2012-02-03 102 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