【问题标题】:Base class and derived class cannot both have a private nested class with the same name?基类和派生类不能都有同名的私有嵌套类?
【发布时间】:2019-02-07 13:27:08
【问题描述】:

我有一个基类和派生类;两者都有一个嵌套类。嵌套类彼此具有相同的名称,但它们是私有的。我想知道为什么这不起作用。

就我而言,嵌套类仅用于内部组织。嵌套类的名称是Properties。我尝试将派生类的Properties 成员标记为声明它的new,但Visual Studio 说没有可以覆盖的成员。

这是我的结构的缩写示例。

class SomeBaseEditor : Editor
{
    private class Properties
    {
        // properties specific to the base gui stored in here
    }

    private Properties properties = new Properties ();

    protected virtual void OnEnable ()
    {
        properties = new Properties (serializedObject);
    }
}
public class SomeBaseEditorImplementation : SomeBaseEditor
{
    private class Properties
    {
        // properties specific to the implementation's gui stored in here
    }
    // tried marking this as new, but Visual Studio said it wasn't hiding a member
    private Properties properties = new Properties ();

    protected override void OnEnable ()
    {
        properties = new Properties (serializedObject);
    }
}

此代码用于 Unity 中的自定义编辑器。有趣的是,错误是在编译之后抛出的——当实际代码运行时。

当基类尝试访问其properties 实例中的成员时,会引发空引用异常。我不认为这会引发错误,因为这两个类都是私有的,不能从任何地方访问。

如果我中断错误并将鼠标悬停在properties 变量上,Visual Studio 会显示它包含派生类的嵌套私有类的成员!?

我将用我的案例中的一个例子来详细说明。基类 Properties 内部有一个 SerializedProperty。派生类的Properties 类有五个SerializedPropertys。当我打破基类的 properties 实例(引发错误的地方)时,它表明它包含来自它的派生类的 5 个SerializedPropertys!! p>

这是我在 Visual Studio 中看到的:

所以它试图访问一个甚至没有声明该成员的类中的成员。我很惊讶这个错误没有在编译时触发,我想知道为什么它一开始就不起作用。

这里是我的两个类的简化版本的链接,可能会为我的高度缩写示例的问题提供更多上下文

【问题讨论】:

  • 这样做完全可以(令人困惑,但可以)。您未显示的其他一些代码的行为方式与您期望的不同,但如果没有minimal reproducible example,就无法对其进行推理。至少一些更完整的类版本可能会有所帮助
  • @AlexeiLevenkov 我相信我的示例代码,在它是 Unity 编辑器代码的上下文中,完全包含了这个问题。但是,我将添加指向我的代码的简化版本的链接,因为我的示例总是可能缺少一些重要的东西。
  • 就像您的屏幕截图一样,显示properties 在某种OnEnable 方法中分配(可能会或可能不会被调用),而您的示例显示properties 在构造函数之前一直分配。跨度>
  • 在我链接的图片中,您可以看到properties 在引发错误的地方不为空,但您是对的,这可能是相关的,我将更新我的代码示例以更清楚字段被初始化的地方。我认为目前这显然是 Unity 的问题,并且可能是它如何序列化编辑器。

标签: c#


【解决方案1】:

你真的没有提供a Minimal, Complete, and Verifiable example。话虽如此,我没有困难拥有一个基类和一个派生类,每个类都有一个具有相同名称的 duplicate 类和具有相同名称的属性。

DotNetFiddle Working Example

public static void Main()
{
    var foo2 = new Foo2();
    foo2.Foo1Go();  //Write "1"
    foo2.Foo2Go();  //Writes "2" then "1"
}

public class Foo1
{
    private class Bar { public int Id { get; private set; } = 1; }
    
    private Bar bar = new Bar();
    
    public void Foo1Go()
    {
        Console.WriteLine(bar.Id);
    }
}

public class Foo2 : Foo1
{
    private class Bar { public int Id { get; private set; } = 2; }
    
    private Bar bar = new Bar();

    public void Foo2Go()
    {
        Console.WriteLine(bar.Id);
        var foo1 = this as Foo1;
        foo1.Foo1Go();
    }
}

结果

1

2

1

【讨论】:

  • 看起来你是对的,C# 代码没有做错任何事情,因此它正在编译。剩下的唯一“未知”是它在 Unity 内部运行。我感觉这是 Unity 序列化 ScriptableObjects 编辑器的问题。
【解决方案2】:

派生类的初始化方法OnEnable 覆盖了基类的OnEnable 而不调用基类的方法,因此从未分配基类的properties 变量。奇怪的是,Visual Studio 没有说变量为 null,但是通过将派生类的 OnEnable 方法更改为调用 base.OnEnable,错误就消失了。

protected override void OnEnable ()
{
    base.OnEnable ();
    properties = new Properties (serializedObject);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-07
    • 2014-06-18
    • 1970-01-01
    • 2018-04-19
    • 1970-01-01
    相关资源
    最近更新 更多