C# 继承:类型与值

C# 继承:类型与值,c#,inheritance,C#,Inheritance,关于继承的快速问题。我有一个基类Baseclass和两个子类subclass 1和subclass 2。我在Baseclass中定义了一个ManualResetEvent Mre,用于取消子类中的方法 在主要形式中,我有: private Baseclass _baseclass; private void Start() { if(XYZ) { var Subclass1 s1 = new Subclass1(); _baseclass = s1;

关于继承的快速问题。我有一个基类
Baseclass
和两个子类
subclass 1
subclass 2
。我在
Baseclass
中定义了一个
ManualResetEvent Mre
,用于取消子类中的方法

在主要形式中,我有:

private Baseclass _baseclass;

private void Start()
{
   if(XYZ)
   {
       var Subclass1 s1 = new Subclass1();
       _baseclass = s1;
       s1.DoCancelableWork();
    }
    else
    {
       var Subclass2 s2 = new Subclass2();
       _baseclass = s2;
       s2.DoCancelableWork();
    }
}

private void Stop()
{
    if(_baseclass != null) _baseclass.Mre.Set();
}

private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
    if(_baseclass != null)
    {
        if(!_baseclass.Mre.WaitOne(0)) Stop();
    }
}

假设
DoCancelableWork()
方法永久运行,直到它从
Baseclass
继承的
Mre
被设置为止(我不再在子类中定义
Mre
)。当运行
Stop()
时,
\u baseclass.Mre
现在是否引用相应子类中使用的
Mre
,因此
DoCancelableWork()
被取消?

是。派生类拥有基类所做的一切(它实际上有一个基类的实例作为它的“一部分”)

因此,如果将派生类实例存储在基类引用中,然后通过该引用对基类成员执行某些操作,则派生类仍然指向/使用它(因为它们实际上是同一个对象)

要澄清您的其他问题:

Subclass s=new Subclass()
,以及
Baseclass b=new Subclass()
。是 有明显的实际区别吗

没有。在功能上没有任何区别。通过将其存储为派生类型,您可以访问仅派生的成员,并且可以避免以后向下转换。如果将其存储为基类,则意味着以后只能作为基类类型访问它(使用多态性获取派生类行为)

比如说,我刚刚有了
子类s1=新的子类()
,但我从来没有这样做过
\u基类=s1
。有没有办法检查一下 基类是否已实例化(正如通过子类实例化的一样)

不需要检查,因为派生类的构造函数语义也总是创建基类。当可用时,它使用默认构造函数。如果不可用,则派生构造函数必须显式调用所需的基类1:

public DerivedClass(string someArg) : base(someArg)
{
}

不清楚您在问什么,但是只有一个
\u基类
的实例,所以无论您将is视为
基类
还是子类,值都是相同的。谢谢,这回答了我的问题。也许这归结为我不太理解
子类s=new Subclass()
,和
基类b=new Subclass()
之间的区别。是否存在明显的实际差异?另外,假设我刚刚有了
子类s1=new Subclass()
,我从来没有做过
\u baseclass=s1
。是否有任何方法可以检查基类是否已被实例化(正如它通过子类所做的那样)?非常感谢!谢谢,布拉德利,非常有帮助。我询问是否有任何方法可以检查
Baseclass
是否已隐式实例化的原因,是由于上面的
Stop()
FormClosing()
方法。他们都希望设置属于当前正在运行的特定
DoCancelableWork()
Mre
(可以是s1中的一个,也可以是s2中的一个)。我不希望在
Stop()
方法中有很多if语句,而是只检查一次基类是否被实例化(因为它有能力停止任何子类)。有没有比设置_baseclass=s1或s2等更好的方法?@Anders我真的不知道你在说什么。基类实例总是在派生类为1时创建的,因此只需调用
s1
s2
等上的
Stop
。将使用适当的实例,因为派生类实例也是基类实例。是的,但我必须将_s1和_s2定义为全局变量。然后,在Stop()中,我必须有多行,每个子类实例一行。相反,我只需要Stop()中的一行和一个全局实例,这样就可以停止相应的子类。如果我有很多子类(s1、s2、s3、…、s50),你可以看到这个问题变得极端。@Anders子类不共享基类实例,就像我说的,它们是一个相同的。所以这永远不会奏效。如果要停止一堆,请将它们保存在列表中并使用
foreach