C# 能否初始化抽象类,以便稍后将其设置为子类?

C# 能否初始化抽象类,以便稍后将其设置为子类?,c#,abstract-class,C#,Abstract Class,这就是我想做的: abstract class BaseAnimal; class cat : BaseAnimal; class dog : BaseAnimal; var allAnimals = new list<BaseAnimal>(); foreach (var someVar in allVars) { var myAnimal = new BaseAnimal(); if (someVar == true) { myAn

这就是我想做的:

abstract class BaseAnimal;
class cat : BaseAnimal;
class dog : BaseAnimal;


var allAnimals = new list<BaseAnimal>();

foreach (var someVar in allVars)
{
    var myAnimal = new BaseAnimal();

    if (someVar == true)
    {
        myAnimal = new cat();
    }
    else
    {
        myAnimal = new dog();
    }


    /* do other things with myAnimal var */
    allAnimals.add(myAnimal);
}

有没有办法做到这一点,或者我必须在每个IF语句中初始化变量,然后复制其他内容/将其放入函数中并调用两次?

只需声明变量而不为其赋值:

BaseAnimal myAnimal;
既然知道该值会立即被覆盖,为什么要给它赋值

请注意,在您的情况下,无论如何,变量肯定会在if/else语句之后赋值,因此这不是问题-在将项目添加到列表时,您仍然能够读取变量值

当然,您也可以考虑使用条件运算符:

var myAnimal = someVar ? (BaseAnimal) new Cat() : new Dog();
这里之所以需要cast to BaseAnimal,是因为条件运算符的工作方式—表达式的整体类型必须是第二个参数的类型或第三个参数的类型

编辑:如果需要设置特定于动物的属性,最简单的方法是在If语句中使用对象初始值设定项:

if (someVar)
{
    myAnimal = new Cat { Lives = 9 };
}
else
{
    myAnimal = new Dog { Shaggy = true };
}
如果需要对其调用方法,则需要一个特定类型的单独局部变量:

if (someVar)
{
    Cat cat = new Cat();
    cat.Groom();
    myAnimal = cat;
}

在这种情况下,您不会初始化它,或者您会将它初始化为null,但是是的,您所要求的是可能的

BaseAnimal myAnimal;

if (someVar) {
    var myCat = new cat();

    // Do things with myCat that are cat-specific.

    myAnimal = myCat;
} else {
    var myDog = new dog();

    // Do things with myDog that are dog-specific.

    myAnimal = myDog;
}

allAnimals.add(myAnimal);
你不能

 var myAnimal = new BaseAnimal();
编译器不允许您这样做。但是,您可以做的是将派生度较高的类强制转换为派生度较低的类,如

BaseAnimal ba = myDog;
你可以按你想要的方式列出你的列表,还可以添加其他动物,比如猫和狗


我有一些猫身上的属性,而不是狗身上的属性,反之亦然。当我尝试上述策略,然后尝试访问cat或dog上的属性时,我得到:BaseAnimal不包含…..的定义。。。。。我是否只需要将这些属性添加到baseAnimal中?如果需要这样做,请在If块内部执行。我将更新我的答案以在代码中显示。@user1652427:那么您需要在哪里访问该属性?看起来你基本上没有给我们你所有的要求,这使得很难给你一个满意的答案…我在IF声明中这样做,但它不起作用@JonSkeet,我试图避免写出所有的代码,因为我最初认为没有必要。@user1652427如果您在If块内完成,那么我更新的代码示例应该适合您。我把它弄混了。。。感谢您的澄清请注意C区分大小写。让您的示例代码尽可能真实是值得的,这意味着使用List而不是List,Add而不是Add,并按照正常约定为类命名。
allAnimals.Add(myDog);