简体   繁体   English

C#未运行派生类函数

[英]C# not running derived class function

I have a problem with a game I'm making. 我正在制作的游戏有问题。 Basically I have a lot of fields, a basic type and other types. 基本上,我有很多字段,基本类型和其他类型。 Logically I made derivatives of the basic field to add the extra functionality as needed. 从逻辑上讲,我对基本字段进行了派生,以根据需要添加其他功能。

However, it seems that when I call a function that is present in the base class, that function will be ran from the base class and not the derivative. 但是,似乎当我调用基类中存在的函数时,该函数将从基类而不是派生类中运行。

Here is some cut-down code so you can see what I mean. 这是一些简化代码,因此您可以了解我的意思。

public class Field
{
    public Field(Field exitN, Field exitE, Field exitS, Field exitW, bool barricadeAllowed, int returnTo, int xPos, int yPos)
    {
        //Actual logic is in the constructor, but unrelated to the below function
    }

    public void Function()
    {
        if (this is StartField)
        {
            Debug.WriteLine("StartField running base function!");
        }
        //Actual logic here. 
    }

}

.

class StartField : Field
{
    public StartField(Field exitN, Field exitE, Field exitS, Field exitW, string color, int xPos, int yPos)
        : base(exitN, exitE, exitS, exitW, false, 0, xPos, yPos)
    {
        //Again, constructor emptied due to unrelatedness. 
    }

    public new void Function()
    {
        Debug.WriteLine("StartField function");
        //Different logic then the base function
    }

Calling this funtion on a startfield object causes the "startfield running base function!" 在startfield对象上调用此功能会导致“ startfield运行基础函数!”。 to appear in my debug bar, but not the "startfield function" This tells me only the base function is called even though the object knows it is of the type StartField. 出现在我的调试栏中,但没有出现在“ startfield函数”中。这告诉我,即使对象知道它是StartField类型,也仅调用了基本函数。

If it makes any difference, all fields are saved through links with other fields. 如果有任何区别,则通过与其他字段的链接保存所有字段。 The variables ask for the type Field, but all are allowed in the variables (because inheritance) Can this in any way cause the call to go to the "Field" code rather then the "StartField" code (or code of any other non standard field, since this seems to be the case with all fields) 变量要求类型为Field,但是所有变量都允许(因为继承),这可以通过任何方式导致调用转到“ Field”代码,而不是“ StartField”代码(或任何其他非标准代码)字段,因为似乎所有字段都是这种情况)

There are 2 workarounds I can think of The first workaround I can think of is checking the type and casting the field to it's actual type before running the function. 我可以想到两种解决方法。我想到的第一种解决方法是在运行函数之前检查类型并将字段强制转换为实际类型。 But we're not allowed to use (class is Field) in the assignment. 但是我们不允许在分配中使用(类是Field)。 Plus it would require more code then needed for a simple function call. 另外,与简单的函数调用相比,它将需要更多的代码。

The second workaround also uses the (class is Field) functionality, namely programming all field type functionality into the base class. 第二种解决方法还使用(类是Field)功能,即将所有字段类型的功能编程到基类中。 Which not only uses (class is Field) but also just feels plain wrong (childs should have their own functionality, doesn't make sense if the base has it all. Might as well go with a single class and have the type be a variable instead of an inheriting member) 它不仅使用(类是Field),而且感觉很普通(子级应该有自己的功能,如果基数全部都没有意义,那么最好只使用一个类并将类型作为变量而不是继承成员)

Basically, it sounds like you need Function to be a virtual method, which is overridden in StartField : 基本上,听起来您需要Function是一个虚拟方法,在StartField对其进行了覆盖

// In Field
public virtual void Function()
{
    if (this is StartField)
    {
        Debug.WriteLine("StartField running base function!");
    }
    //Actual logic here. 
}

// In StartField
public override void Function()
{
    Debug.WriteLine("StartField function");
    //Different logic then the base function
}

Your current code is not using polymorphism - it will always call Field.Function if the compile-time type of the expression you're calling Function on is just Field , because it's not virtual. 您当前的代码使用多态性-如果您正在调用Function的表达式的编译时类型仅为Field ,则它将始终调用Field.Function ,因为它不是虚拟的。 Then in StartField you're explicitly saying, "I'm not trying to override the base method - I'm providing a new one." 然后,在StartField您明确地说:“我不打算覆盖基本方法-我提供了一个新方法。”

See the MSDN page for the new modifier and the one on the virtual modifier for more details. 有关new修饰符 ,请参见MSDN页面; 有关virtual修饰符的信息,请参见MSDN页面

What if Function was made virtual ? 如果将Function 虚拟化了怎么办?

public virtual void Function()
{
    if (this is StartField)
    {
        Debug.WriteLine("StartField running base function!");
    }
    //Actual logic here. 
}

And then overridden in StartField , like this: 然后在StartField重写,如下所示:

public override void Function()
{
    Debug.WriteLine("StartField function");
    //Different logic then the base function
}

Definitely don't try to work around this -- it's basic OOP. 绝对不要尝试解决此问题-这是基本的OOP。

You need to mark the base class method as virtual (or abstract, if it doesn't have its own logic) so that it can be overridden. 您需要将基类方法标记为虚方法(如果没有自己的逻辑,则标记为抽象),以便可以将其覆盖。 Then mark the subclass method as an override. 然后将子类方法标记为重写。 Check http://msdn.microsoft.com/en-us/library/ebca9ah3(v=vs.110).aspx for example. 例如,检查http://msdn.microsoft.com/en-us/library/ebca9ah3(v=vs.110).aspx

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

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