【问题标题】:Strange behaviour of WPF project (class naming)WPF项目的奇怪行为(类命名)
【发布时间】:2011-03-25 17:59:36
【问题描述】:

尝试在解决方案ExpertSystem 中构建我的项目ExpertSystem 时遇到一个奇怪的错误:

错误 1 ​​类型名称 'App' 没有 存在于类型中 'ExpertSystem.ExpertSystem' D:\Users\Kirill\Documents\Visual 工作室 2010\Projects\ExpertSystem\ExpertSystem\obj\x86\Debug\App.g.cs 60 26 专家系统

我什至不知道 VS 在构建时会创建这个文件。所以,我开始在我上次编辑的代码中搜索问题,发现问题出在我的最后一堂课中:

namespace ExpertSystem
{
    public class ExpertSystem
    {
    //...
    }
}

当类名更改为不同于ExpertSystem 的名称时,项目编译不会出错。

谁能解释一下,我真的可以在 C# 中拥有与命名空间/项目/解决方案同名的类吗?还是这是某种 VS/WPF 错误?

谢谢。

【问题讨论】:

    标签: c# wpf visual-studio-2010 class naming


    【解决方案1】:

    VS 为每个 XAML 文件生成部分类(不是在构建期间,而是在设计期间),以便(例如)将命名组件声明和填充为类字段。

    如果您想轻松阅读设计器生成的 App.g.css 文件(与 App.xaml 和 App.xaml.cs 文件相关联)的内容,请转到 App.xaml.cs 文件并执行“在类构造函数中的 InitializeComponent() 函数调用上转到定义”。我不知道你身上潜伏着什么,但我希望设计师会产生这样的东西(也许不是这样,但问题是一样的):

    var foo = (SystemExpert.App)(Application.Current)
    

    应该理解为:

    var foo = (global::SystemExpert.App)(Application.Current)
    

    现在,如果您在 SystemExpert 程序集命名空间中创建一个 SystemExpert 类,并且 App 类也在 SystemExpert 命名空间中声明,编译器将理解:

    var foo = (global::SystemExpert.SystemExpert.App)(Application.Current)
                ^^^^^^^^^^^^^^^^
             the current namespace
    

    将类命名为与命名空间完全相同的做法是不好的做法:它会混淆编译器。

    【讨论】:

      【解决方案2】:

      谁能解释一下,我真的可以在 C# 中拥有与命名空间/项目/解决方案同名的类吗?

      是的,你可以。它是 C# 语言的一部分。

      因此,编译器无法确定代码是要查找 ExpertSystem.ExpertSystem 命名空间还是 ExpertSystem 命名空间中的 ExpertSystem 类。 (可以,但它弄错了。)

      【讨论】:

      • 我还没有开始在该类的代码中的任何地方使用的问题。刚刚定义好了。所以请给我一个建议,我该如何解决这个问题?对我来说最好留下那个班级的名字。
      • @archer:你为什么不能用不同的名字?
      • 如果重命名类是唯一可行的方法,我可以。
      • 真的,编译器认为Main() ExpertSystemExpertSystem.App app = new ExpertSystem.App(); 是我的类,而不是命名空间。如果我更改为App app = new App(); 则可以...但最好重命名类。感谢您的帮助。
      【解决方案3】:

      为了补充BoltClock's answer 的解决方案,在保持命名空间和类名不变的同时工作:

      错误报告在一个名为App.g.cs 的文件中,该文件由编译器生成。因此,修复该文件中的问题将无济于事,因为该文件将在下次编译时被错误覆盖(或在您将代码复制到另一台机器后重写)。

      但是,您可以更改生成 App.g.csApp.xaml 文件。文件的根元素将以类似

      的内容开头
      <Application x:Class="ExpertSystem.App"
      

      在那里,应该可以找到命名空间ExpertSystem,但是对于具有相同名称的类,编译器假定App 是您的类ExpertSystem.ExpertSystem 中的成员或嵌套类型。

      通过思考这一点,您将意识到编译器出于某种原因首先尝试评估 x:Class 属性相对于 ExpertSystem 命名空间的值。这种行为是造成您的问题的原因,但由于我们现在知道行为的细节,我们可以相应地编写代码 - 使用相对于命名空间 ExpertSystem 限定的标识符:

      <Application x:Class="App"
      

      在此更改之后,它应该可以正常编译,即使命名空间和类都命名为ExpertSystem

      【讨论】:

        猜你喜欢
        • 2017-05-10
        • 1970-01-01
        • 2013-05-13
        • 1970-01-01
        • 1970-01-01
        • 2012-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多