【问题标题】:Protection level of a struct field within a class类中结构字段的保护级别
【发布时间】:2011-07-24 07:26:09
【问题描述】:

我是 C# 编程的新手,所以这可能是一个初学者的问题。

我在以下代码 sn-p 上收到 “'A.Test.That.Fails' is inaccessible due to its protection level” 错误,我无法理解原因。

namespace A
{
    class Test
    {
        public void Demo()
        {
            That[] it = new That[42];
            it[0].fails = 21;
        }

        public struct That
        {
            int fails;
        }
    }
}

来自 C++ 编程并阅读过保护规则几乎相同,因为只有一个类,即使 That 结构和 Demo 方法都是 private,我也希望它能够工作。

作为旁注,我们将非常感谢您提供指向 C++ 程序员范围和保护规则的总结页面的链接。

【问题讨论】:

  • A.Test.That.fails... 聪明。 +1
  • 见科迪的回答; C#中的结构和类有很大的区别;事实上,它们几乎没有关系。大多数时候人们在 C# 中使用结构,这是不正确的。确保您出于正确的原因使用它。 “因为它是一个简单的对象”不是这样的理由。
  • @BoltClock: ;) @Marc: 将“因为我只想要一个快速的标量对数组”作为借口吗?
  • 是的,我会这么说。不一定是因为它简单或快速,而是因为您需要这些标量对的值类型语义。它们应该像普通的int 一样工作,而不是像一个对象。它们是不可变的,这是合乎逻辑的。我也会为此选择一个结构。
  • 切题:如果您不想要您的内部信息公开但无论如何都需要它们公开,InternalsVisibleTo 允许您创建一个内部类对特定的外部程序集可见。这对于单元测试非常有用。

标签: c# struct visibility protection


【解决方案1】:

其他给出的答案已经有了你的答案,这里就不废话了。您需要声明字段public 以便能够从外部代码访问它。

在 C++ 中,结构和类是等价的,唯一的区别是它们各自成员的默认访问级别。

但是,在 C# 中并非如此。通常,您应该只将结构用于不可变(不会更改)的小型、短暂的对象。结构具有值类型语义,而类具有引用类型语义。如果您正在学习 C# 编程,那么了解值类型和引用类型之间的区别非常重要。 Jon Skeet 发表了an article 试图提供这种解释。但您肯定会想要一本很好的 C# 入门书籍,更详细地处理这些问题。

通常情况下,您会希望在 C# 中使用类,而不是结构。当您使用该类时,请注意 Microsoft 的 C# 设计指南倾向于建议反对公开公共字段。相反,他们建议您使用由私有字段支持的公共属性。 here 给出了对该准则背后基本原理的更全面说明。例如:

class TimePeriod
{
    private double seconds;

    public double Seconds
    {
        get { return seconds; }
        set { seconds = value; }
    }
}

或者您可以使用更简单的“自动属性”语法,它让编译器自动生成该私有支持字段:

class TimePeriod
{
    public double Seconds { get; set; }
}

【讨论】:

  • 是的,为了这个例子,我确实公开了,但在现实生活中,事情确实尽可能私密,这种定义 set/get 的能力显然有帮助。感谢您的概述和链接。
  • @Julien:当然。我假设这个例子只是为了演示目的而设计的。显然,在现实世界中确实存在您想要使用结构的合理情况。不仅用于值类型语义,还用于互操作目的。但总的来说,最好使用 C# 中的类对对象进行建模。
  • +1 Win32 互操作迫使我在我的 WPF 应用程序中过度使用结构......我很讨厌它。
  • @Bolt:当然,我假设您已将所有这些结构放在单独的命名空间和/或程序集中,并声明它们是私有的或内部的。我总是在互操作代码上编写一个漂亮、干净的托管包装类,这是我公开公开的唯一内容。
【解决方案2】:

C# 中结构字段(和类字段)的默认访问修饰符是private。所以int fails; 对你的结构来说是私有的,除非你将它声明为公共的。

【讨论】:

    【解决方案3】:

    请看this question的答案

    默认情况下该成员被声明为私有 - 您需要在其前面添加 public 修饰符。

    【讨论】:

      【解决方案4】:

      因为fails 不是public.. 默认情况下struct 中的字段甚至class 都是private

      根据MSDN

      class 成员和 struct 成员(包括嵌套类和结构)的 访问级别private默认

      【讨论】:

      • 好吧,我明白了,不像 C/C++ 结构字段默认是公共的。谢谢。
      • 不客气。我添加了指向 MSDN 文档的链接供您参考。 :)
      【解决方案5】:

      Test 的私有成员仅限于 Test 本身,并且在 Test 之外不可用。演示不在测试范围内。父母是谁并不重要。

      在Test里面定义Demo,就可以访问私有成员了。

      【讨论】:

      • 当然。它不在Test的定义之内,所以它在外面。 QED。要在里面,它需要在 Test 结构本身的大括号内。
      猜你喜欢
      • 1970-01-01
      • 2019-04-21
      • 2010-10-18
      • 1970-01-01
      • 1970-01-01
      • 2012-03-30
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多