简体   繁体   English

C#隐式类型变量重新初始化

[英]C# Implicitly Typed Variable re-initialize

How do I re-initialize a Implicitly Typed Variable (var) in C#? 如何在C#中重新初始化隐式类型变量(var)?

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

Right now I have it like above and I am getting an error. 现在我就像上面那样,我收到了一个错误。

Cannot implicitly convert type 'Class1' to 'Class' 无法将类型'Class1'隐式转换为'Class'

You can't. 你不能。 var doesn't work like that. var不能那样工作。 var means "look, I'm too lazy to type out the real statically typed name of this variable, can you just figure it out for me?" var意味着“看,我懒得输入这个变量的真正静态类型名称,你能解决一下吗?” That's what implicit typing means. 这就是隐式打字的含义。

So, on the first line, the compiler decides that abc is typed as a reference to Class . 因此,在第一行,编译器决定将abc键入为Class的引用。 Then, you later try to assign a reference to Class1 to abc . 然后,您稍后尝试将Class1的引用分配给abc Of course that's impossible unless there's a conversion from Class1 to Class . 当然,这是不可能的,除非有从转换Class1Class

To stress, your code is as if you'd written 要强调,你的代码就像你写的一样

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

In fact, it's semantically identical. 实际上,它在语义上是相同的。 But now your error is obvious. 但现在你的错误是显而易见的。 You're trying to assign a reference to Class1 to abc but abc can't accept that unless there's an implicit conversion from Class1 to Class . 您正尝试Class1的引用分配给abc但除非存在从Class1Class的隐式转换,否则abc无法接受。

Implicit typing with var is still static typing 使用var的隐式类型仍然是静态类型

var abc = new Class();

is exactly equivalent to 完全等同于

Class abc = new Class();

Unless Class1, Class2 and Class3 extend Class, you can't assign them to abc. 除非Class1,Class2和Class3扩展Class,否则不能将它们分配给abc。

在这种情况下,如果Class1 / 2/3显式继承自Class,则不能这样做。

You don't. 你没有。 Implicit initialization is determined by the compiler at the point of assignment, thus your first line: 隐式初始化由编译器在赋值时确定,因此您的第一行:

var abc = new Class();

Is equivalent to: 相当于:

Class abc = new Class();

So once it's determined to be of type Class it can't be changed any more than the explicit declaration can. 因此,一旦确定它是Class类型,它就不能比显式声明更改。

Perhaps you were wanting to do dynamic typing instead? 也许你想要做dynamic打字呢?

You Can't do what you ask but you can do this. 你不能做你要求但你可以做到这一点。

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

While this doesn't provide a lot of value. 虽然这并没有提供很多价值。 If all of the classes inherit from a common class or interface that does some work you need to do it may be what you are going for. 如果所有类都继承自公共类或接口,那么您需要执行某些工作,这可能就是您的目标。 So for example 所以举个例子

        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() 

The sleep would then invoke the correct function for which ever type it accentual was. 然后,睡眠会调用正确的函数,而这种函数的类型就是它的重音。

You can do this var abc = new Class(); 你可以这样做var abc = new Class(); , beacuse var is a generic type and when you do this you are doing exactly Class abc = new Class(); ,beacuse var是一个泛型类型,当你这样做时,你正在做的Class abc = new Class(); . The problem is when you try to do re-initalize . 问题是当你尝试re-initalize But you wrong,after when you do abc = new Class1(); 但你错了,在你做abc = new Class1(); , you're not reinitializing abc but you're passing the pointer of the new object of type Class . ,你不是要重新初始化abc而是传递类型为Class的新对象的指针 So the compiler say that you cannot do this convertion, beacuse the type of abc is Class . 所以编译器说你不能做这个转换,因为abc的类型是Class

But you can use object , as said Mark Backett , because the type object is the base class of all classes. 但是你可以像Mark Ba​​ckett那样使用object ,因为type object是所有类的类。

Also a solution could be something like this: 另外一个解决方案可能是这样的:

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{ ... }

You cannot do this. 你不能做这个。 It's just an equivalent way of writing 这只是一种等效的写作方式

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

which obviously would not work in the general case. 这显然不适用于一般情况。

An implicitly typed variable still respects polymorphism - so your inferred variable is of type Class : 隐式类型变量仍然遵循多态 - 因此您的推断变量的类型为Class

Class abc = new Class();

Since Class1 does not (presumably) inherit from Class , it's invalid to reassign. 由于Class1不(可能)继承自Class ,因此重新分配是无效的。 If you want to type an inferred variable to a less restrictive base type (eg., object), you can either write out the declaration (preferred) or cast the right hand side so that the compiler infers a different type: 如果要将推断变量键入限制较少的基类型(例如,对象),则可以写出声明(首选)或强制转换右侧,以便编译器推断出不同的类型:

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

A little late to the party but why not: 派对有点晚,但为什么不呢:

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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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