【问题标题】:Partial class in different namespaces不同命名空间中的部分类
【发布时间】:2011-05-29 02:31:17
【问题描述】:

我可以在不同的命名空间中创建部分类吗?它会正确工作吗? 例如:

class1.cs

namespace name1
{
    public partial class Foo
    {
        Bar1(){
            return 10;
        }
    }
}

class2.cs

namespace name1.name2
{
    public partial class Foo
    {
        Bar2(){
            return 100;
        }
    }
}

main.cs

using name1;
using name1.name2;

namespace mainClass
{
    public class mainClass
    {
        Foo classFoo = new Foo();
        int Count = classFoo.Bar1() + classFoo.Bar2();
        // Will Count = 110?
    }
}

我应该怎么做才能让它工作? (如果我的例子不正确)

【问题讨论】:

    标签: c# .net class namespaces partial


    【解决方案1】:

    一个类的名称包括它的命名空间,所以name1.Fooname1.name2.Foo 是两个完全不同的类型。所以你的问题的简短回答是:不。

    为什么你需要做这样的事情?

    【讨论】:

    • 我想创建单独的库。在不修改主类的情况下向主类添加新功能。关于这个话题,我脑子里有一个很大的洞......
    • 好吧,我建议两种可能性。第一个是在name1.name2.Foo 中为name1.Foo 创建一个子类。第二种方法是使用扩展方法 (msdn.microsoft.com/en-us/library/bb383977.aspx),这是向您无法控制或出于任何原因不想修改的类“添加”功能的好方法。
    • @RAMe0:Partial 类在编译时解析,在 .NET 中没有 Partial 类型的意义,它是一种语言结构。它允许一个类的源代码在编译过程中出现在多个源文件中。
    • (这就是我想要的)[docs.google.com/document/d/…我只想到一件事...如果我要创建项目并像“Name1.n2”、“Name1.n3”、“ Name1.n4".... 但是有 1 个命名空间和部分类,dll 的名称看起来像 "Name1.n2"、"Name1.n3"... 我可以像示例文档中那样使用它吗?
    • @RAMe0 我建议使用继承。这也许是解决方案
    【解决方案2】:

    这行不通。编译器会在 Foo classFoo = new Foo(); 行上给你一个模棱两可的名称错误。要使部分类工作,它们必须在同一个命名空间中,因为命名空间实际上是类型的完全限定名称的一部分。

    【讨论】:

    • 我明白这一点,这就是我问的原因......请阅读对先前答案的评论
    • @Coding Gorilla 的评论是正确的。如果您只是想为一个类型添加方法,那么子类化(如果该类型不是密封的)或使用扩展方法都是可行的方法。
    【解决方案3】:

    只能在同一命名空间和同一程序集中使用部分类

    命名空间可以在两个不同的程序集中,但部分类不能。

    【讨论】:

      【解决方案4】:

      在实现部分类时需要考虑以下几点:-

      • 在partial类的各个部分使用partial关键字。

      • 部分类的每个部分的名称应该相同,但部分类的每个部分的源文件名可以不同。

      • 分部类的所有部分都应该在同一个命名空间中。

      • 分部类的每个部分都应该在同一个程序集或 DLL 中,换句话说,您不能在不同类库项目的源文件中创建分部类。

      • 分部类的每个部分都具有相同的可访问性。 (如私有、公共或受保护)

      • 如果您在分部类上继承类或接口,那么它会在分部类的所有部分上继承。

      • 如果部分类的一部分被密封,那么整个类将被密封。

      • 如果部分类的一部分是抽象的,那么整个类将被视为抽象类。

      https://www.codemaggot.com/partial-classes-in-csharp/

      【讨论】:

        【解决方案5】:

        MSDN https://msdn.microsoft.com/en-us/library/wa80x488.aspx对部分类和方法的限制

        【讨论】:

          【解决方案6】:

          此外,对于静态类,您可以借助新的 C# 6.0 using static feature 实现类似的功能。

          考虑:

          namespace SomeLogic1
          {
              public static class Util
              {
                  public static int Bar1()
                  {
                      return 1;
                  }
              }
          }
          
          namespace SomeLogic2
          {
              public static class Util
              {
                  public static int Bar2()
                  {
                      return 2;
                  }
              }
          }
          
          namespace GeneralStuff
          {
              using SomeLogic1;
              using SomeLogic2;
          
              public class MainClass
              {
                  public MainClass()
                  {
                      // Error CS0104
                      // 'Util' is an ambiguous reference between 'SomeLogic1.Util' and 'SomeLogic2.Util'
                      var result = Util.Bar1() + Util.Bar2(); 
                  }
              }
          }  
          

          对,就是不编译,错误信息很清楚。要解决这种情况,您可以直接指定命名空间(但据我了解,您不希望这样做):

          namespace GeneralStuff
          {
              public class MainClass
              {
                  public MainClass()
                  {
                      var result = SomeLogic1.Util.Bar1() + SomeLogic2.Util.Bar2(); 
                  }
              }
          }
          

          或者您可以通过这种方式应用使用静态功能:

          namespace GeneralStuff
          {
              using static SomeLogic1.Util;
              using static SomeLogic2.Util;
          
              public class MainClass
              {
                  public MainClass()
                  {
                      var result = Bar1() + Bar2(); 
                  }
              }
          }
          

          也许对一些助手/实用程序类这样做是可以的。但正如其他人所注意到的那样,部分类不是方法。

          【讨论】:

            【解决方案7】:

            我假设您的主要目标是在不同的命名空间之间分配方法,否则这将是微不足道的(将所有内容放在一个类中,无论是否部分都完成了)。

            所以假设的目标是:

            • 在命名空间name1 中有两个方法Bar1Bar2 在命名空间name1.name2
            • 能够在一个类的上下文中调用上述任何方法,这里是ClsFoo

            您无法使用部分类来实现这一点,但您可以通过不同的方式实现它:如果您使用 扩展方法 并将它们绑定到特定类(此处为 ClsFoo),那么您可以执行以下操作:

            using SomeOtherNamespace;
            using name1;
            using name1.name2;
            
            namespace mainClass
            {
                public static class mainClass
                {
                    public static void Main()
                    {
                        var classFoo = new ClsFoo();
                        var count = classFoo.Bar1() + classFoo.Bar2();
                        Console.WriteLine($"count = {count}"); // output is 110
                    } // main               
                } // class
            } // namespace
            
            namespace SomeOtherNamespace
            {
                public class ClsFoo
                {
                    // does not need to contain any code
                } // class
            } // namespace
            
            namespace name1
            {
                public static class FooExt
                {
                    public static int Bar1(this ClsFoo foo)
                    {
                        return 10;
                    } // method
                } // class
            } // namespace
            
            namespace name1.name2
            {
                public static class FooExt
                {
                    public static int Bar2(this ClsFoo foo)
                    {
                        return 100;
                    } // method
                } // class
            } // namespace
            

            Run it online

            这样,你声明一个空类ClsFoo,然后编写一些扩展方法Bar1()Bar2(),它们驻留在不同的命名空间和静态扩展类中。

            注意:扩展类可以有相同的名称FooExt,只要它们在不同的命名空间中,当然你也可以给它们不同的名称,如FooExt1FooExt2 if你喜欢 - 这个例子仍然有效;即使在旧版本的 C# 中也是如此。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2020-05-02
              • 1970-01-01
              • 2011-04-24
              • 1970-01-01
              • 1970-01-01
              • 2016-02-11
              • 2012-07-31
              相关资源
              最近更新 更多