C# 为什么要将派生类的实例分配给类型不是实例类型而是其基类的变量

C# 为什么要将派生类的实例分配给类型不是实例类型而是其基类的变量,c#,polymorphism,C#,Polymorphism,我有5年的工作经验。但老实说,虽然我知道并使用这个结构 Baseclass bc = new DerivedClass(); 我不知道它到底是干什么的,不是真的,不是真的。它是派生类还是基类?我知道如果我调用bc.Method(),我将得到派生类方法。但只有当我使用新的关键字或覆盖或什么的时候。老实说,我开始有点模糊了,我想我需要回到最基本的方面,有人能给我指出正确的方向吗?它只需创建一个DerivedClass的实例,并将其分配给类型为BaseClass的bc它只需创建一个DerivedC

我有5年的工作经验。但老实说,虽然我知道并使用这个结构

Baseclass bc = new DerivedClass(); 

我不知道它到底是干什么的,不是真的,不是真的。它是派生类还是基类?我知道如果我调用bc.Method(),我将得到派生类方法。但只有当我使用新的关键字或覆盖或什么的时候。老实说,我开始有点模糊了,我想我需要回到最基本的方面,有人能给我指出正确的方向吗?

它只需创建一个
DerivedClass
的实例,并将其分配给类型为BaseClass的bc

它只需创建一个
DerivedClass
的实例,并将其分配给类型为BaseClass的bc

它创建一个
DerivedClass
的实例,并将其分配给类型为
基类

我假设这是编译,这意味着
DerivedClass
继承自
Baseclass
,例如:

class DerivedClass : Baseclass
{
}
或者在这些类型之间有一个用于铸造的

class DerivedClass
{
    public static implicit operator Baseclass(DerivedClass d)
    {
        // return a Baseclass here
    }
}

它创建一个
DerivedClass
的实例,并键入
Baseclass

我假设这是编译,这意味着
DerivedClass
继承自
Baseclass
,例如:

class DerivedClass : Baseclass
{
}
或者在这些类型之间有一个用于铸造的

class DerivedClass
{
    public static implicit operator Baseclass(DerivedClass d)
    {
        // return a Baseclass here
    }
}
使用以下命令

如果我们创建了
Employee
的一个新实例,但我们的变量声明实际上是
Person
,那么将发生的只是对
Person
的隐式转换,这意味着我们将无法访问
Employee
中的任何方法或属性。如果
Employee
的构造函数影响
Person
的构造函数,我想这可能很有用,但是我们不关心
Employee
中的任何内容,但是我不推荐它。相反,我建议构建一种利用更清晰多态性的方法。例如,当派生对象用作参数时,实际上参数类型是它的一个基的类型

public void DoSomething(Employee employee)
{
    // here we do something with an employee
    // ...

    string fullName = GetTheirFullName(employee);
}

public string GetTheirFullName(Person person)
{
    return (person.FirstName + " " + person.LastName).Trim();
}
使用以下命令

如果我们创建了
Employee
的一个新实例,但我们的变量声明实际上是
Person
,那么将发生的只是对
Person
的隐式转换,这意味着我们将无法访问
Employee
中的任何方法或属性。如果
Employee
的构造函数影响
Person
的构造函数,我想这可能很有用,但是我们不关心
Employee
中的任何内容,但是我不推荐它。相反,我建议构建一种利用更清晰多态性的方法。例如,当派生对象用作参数时,实际上参数类型是它的一个基的类型

public void DoSomething(Employee employee)
{
    // here we do something with an employee
    // ...

    string fullName = GetTheirFullName(employee);
}

public string GetTheirFullName(Person person)
{
    return (person.FirstName + " " + person.LastName).Trim();
}

您正在创建DerivedClass的实例,并将其分配给BaseClass类型的变量。如果您有两个派生类Fish和Dog的基类Animal,但您不知道将实例化哪一个,这在您的上下文中并不重要,因为您将调用基类中定义的方法。例如,您可以有如下内容:

Animal a;
if (whatever you want)
    a = new Dog();
else
    a = new Fish();
a.Feed();

使用修改器时要小心,因为如果您使用virtual定义了Feed-in-Animal,并使用override在Fish中重新定义了Feed-in-Animal,则将执行Fish版本(它在执行时链接)。如果不将基本版本标记为虚拟版本,而将Fish版本标记为新版本,则将执行动物版本(它在编译时链接)。

您正在创建DerivedClass的实例,并将其分配给BaseClass类型的变量。如果您有两个派生类Fish和Dog的基类Animal,但您不知道将实例化哪一个,这在您的上下文中并不重要,因为您将调用基类中定义的方法。例如,您可以有如下内容:

Animal a;
if (whatever you want)
    a = new Dog();
else
    a = new Fish();
a.Feed();

使用修改器时要小心,因为如果您使用virtual定义了Feed-in-Animal,并使用override在Fish中重新定义了Feed-in-Animal,则将执行Fish版本(它在执行时链接)。如果您不将基本版本标记为虚拟版本,而将Fish版本标记为新版本,则将执行动物版本(它在编译时链接)。

5年的经验是什么?您询问将扩展类实例化为基类的意义,对吗?为什么不发布一个简单的类结构来说明您的意思呢?首先为上述场景创建一个控制台应用程序,并逐步完成代码块,这可能有助于刷新和删除模糊性,看看多态性(C#编程指南)-这与您的案例非常相似。5年的经验是什么?您询问将扩展类实例化为基类的意义,对吗?为什么不发布一个简单的类结构来说明你的意思呢?首先为上述场景创建一个控制台应用程序,并逐步完成代码块,这可能有助于刷新和删除模糊性。看看多态性(C#编程指南)-它与你的情况非常相似。挑剔:实际上它将创建的实例分配给bc,它是BaseClass类型。
bc
实际上是类型“handle to
BaseClass
”挑剔:实际上它将创建的实例分配给bc,它是类型BaseClass。
bc
实际上是类型“handle to
BaseClass
”Francesco,这是一个伟大的响应,我现在可以清楚地看到它了!谢谢你…虚拟和覆盖的硬币也掉了。弗朗西斯科,这是一个伟大的回应,我现在能看清楚了!谢谢你…虚拟和超控的硬币也掉了。