为啥命名空间中定义的元素不能显式声明?

Posted

技术标签:

【中文标题】为啥命名空间中定义的元素不能显式声明?【英文标题】:Why elements defined in a namespace cannot be explicitly declared?为什么命名空间中定义的元素不能显式声明? 【发布时间】:2012-02-27 19:19:57 【问题描述】:

我有以下 C# 代码:

namespace ISeeOptic.BL


  public abstract class Process
          
     ...      

     protected static void DeleteImages(List<ImagesPath> list)
      
          some logic
       

      ...
   


    protected class GetDataBL: Process
    
      ...

     public static void DeleteImages(List<ImagesPath> list)
     
         DeleteImages(list); 
      
     ...
 
 

在编译时出现以下错误:

命名空间中定义的元素不能显式声明为私有、受保护或受保护的内部

我是 C# 的初学者,所以这个问题可能看起来很幼稚, 知道导致此错误的原因是什么吗?

谢谢你。

【问题讨论】:

你在运行时或编译时得到这个? 【参考方案1】:

命名空间中定义的元素可以显式声明为公共的或内部的。

它们可能不会被显式声明为私有或受保护(或受保护的内部),因为这些修饰符仅对类的成员有意义。

例如,您的protected class GetDataBL 没有意义,因为“受保护”的意思是“继承自包含类的类可以访问”——但 GetDataBL 没有包含类。

【讨论】:

【参考方案2】:

private protected 表示此类或派生类可以访问它们。 在 Namespace 级别中没有派生类,所以它没有用。

您只能在Namespace 级别中使用publicinternal

MSDN docs

【讨论】:

如果我想拥有一个只有命名空间中的其他对等类才能访问的类怎么办? @SamuelCabrera,你知道怎么做吗?我也需要这种行为。【参考方案3】:

(我相信你实际上会得到一个编译时错误;如果你只是在执行时看到这个,那么你的代码很可能也在执行时被编译,例如Web 应用程序的一部分。从逻辑上讲,这是编译时错误,而不是异常。)

protected 访问修饰符(松散地)使成员可以被派生的包含类型访问;但在命名空间成员的情况下, 没有包含类型。

同样,私有成员的可访问域是包含类型的程序文本——同样,没有包含类型。

通过使GetDataBL 受到保护,您实际上试图实现什么?

【讨论】:

【参考方案4】:

正如错误和 C# 规范(ECMA 第 10.5.1 节)所解释的,这是导致错误的元素的范围:

在编译单元或命名空间中声明的类型可以具有 publicinternal 声明的可访问性,默认为 internal 声明的可访问性。 类成员可以具有五种声明的可访问性中的任何一种,默认为private 声明的可访问性。 结构成员可以有 publicinternalprivate 声明的可访问性,默认为 private 声明的可访问性,因为结构是隐式密封的。

【讨论】:

【参考方案5】:

在类 Private、Protected 和 Protected Internal 访问说明符不允许在命名空间级别。

只有允许的说明符在类中是公共的和内部的。

只允许对子类私有、受保护或受保护的内部访问说明符。

示例代码

internal class ParentClass

    public string test()
    
        return "This is the parent class function";
    
    private class BaseChildClass
    
        protected string childtest()
        
            return "This is the parent class function";
        
    

    private class DerivedChildClass : BaseChildClass
    
        private void test1()
        
            string test = base.childtest();

        
    

【讨论】:

以上是关于为啥命名空间中定义的元素不能显式声明?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能使用双冒号在命名空间中前向声明一个类?

具有显式默认命名空间的 XML 文档的 XPath 和命名空间规范

在输出中的元素上显式显示默认命名空间

为啥要将类型放在未命名的命名空间中?

为啥我不能创建在与类定义相同的命名空间中定义的 C++ 类的实例?

为啥内联未命名的命名空间?