不同命名空间中的部分类

Posted

技术标签:

【中文标题】不同命名空间中的部分类【英文标题】: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?
    

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

【问题讨论】:

【参考方案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# 中也是如此。

【讨论】:

以上是关于不同命名空间中的部分类的主要内容,如果未能解决你的问题,请参考以下文章

SWIG / C#:命名空间和模板

Python中的命名空间是啥?

第七天

交友/使用不同命名空间中的类

处理 R 中冲突的命名空间(不同包中的相同函数名):重置包命名空间的优先级

python命名空间和作用域