【问题标题】:Do properties always have a value when unset?未设置时属性是否始终具有值?
【发布时间】:2012-02-20 12:28:18
【问题描述】:

我有这样的财产:

public Tuple<String, String>[] Breadcrumbs { get; set; }

我在我的一种方法中进行了测试,如下所示:

if (Breadcrumbs != null && Breadcrumbs.Length > 0) { }

根据调用此方法的时间,Breadcrumbs 可能尚未设置。在一项测试中,Breadcrumbs == null 评估为真。

未设置的属性总是有值吗? (会一直是null吗?)

【问题讨论】:

    标签: c# .net properties


    【解决方案1】:

    未由任何代码显式设置的自动实现的属性将始终具有属性类型的默认值 - 对于引用类型,默认值为 null。 (int 为 0,char 为 '\0' 等)。

    像这样自动实现的属性只是相当于:

    private PropertyType property;
    public PropertyType Property
    {
        get { return property; }
        set { property = value; }
    }
    

    ...除了支持变量有一个难以描述的名称(你不能在代码中引用它),所以它总是以类型的默认值开始。

    【讨论】:

    • 外星名字哈哈哈
    【解决方案2】:

    自动属性使用支持字段并编译为常规属性。

    如果 Property-Type 是引用类型,则值为 null,否则为默认值。

    【讨论】:

      【解决方案3】:

      类成员变量(称为字段)以及属性的支持变量,如果没有显式初始化,则始终初始化为其默认值,对于引用类型为null。所有类型的默认值是其二进制表示由所有设置为 0 的位组成的值。

      另一方面,C# 要求您显式初始化局部变量。它们是:在方法、构造函数和属性访问器中声明的变量以及out 方法参数;即,在您为其赋值之前,它们将被视为未定义。

      【讨论】:

      • 哎呀,到目前为止,我一直在编写 C# 代码,我的印象是我必须初始化所有内容,否则可能会发现大量随机垃圾。不过我想我会保持这个习惯,所以当我回到 C 语言时,我不会犯那些非常微妙的错误。
      • C#编译器擅长检测潜在的未初始化变量,所以不用太担心!
      • @Oliver:不,你永远不会找到随机垃圾;内存管理器总是初始化它。 (在安全代码中;在不安全代码中,您只能靠自己。这就是它被称为“不安全”的原因。)但是,C# 确实要求您在读取所有局部变量之前显式初始化它们;这不是为了防止你看到垃圾,而是为了防止你写错误。
      • @EricLippert 说,我想不出那些不坚持初始化的语言中的错误 a) 有一个默认值集,而编码器没有预料到它,导致错误或 b) 那里有随机垃圾,而编码人员没想到会导致错误。一个假设的 C# 允许使用未初始化的本地变量将不得不导致一个或另一个。 (我猜前者也会导致太多的验证问题)。还有其他可能吗?
      【解决方案4】:

      它没有值在逻辑上是不可能的。它必须返回一些东西,一些 1 和 0,至少被认为是对 Tuple&lt;String, String&gt;[] 的引用,因此在某种程度上它是有价值的。

      在这种情况下,类中的所有字段都设置为其默认值(default(T) 用于任何类型的 T,对于所有引用类型,null)。否则,可能会有一个对象处于这样一种状态,这种状态不仅就它的作用而言没有任何意义,而且根据 .NET 期望对象执行的规则也没有任何意义。这包括自动属性背后的隐藏字段。

      现在,在某些语言中,我们可以这样做:

      public Tuple<String, String>[] Breadcrumbs
      {
        get
        {
          Tuple<String, String>[] whatIWillSend;
          return whatIWillSend;
        }
      }
      

      如果允许,whatIWillSend 的值将不是由您的任何有意识的决定定义的,而是由当时发生在内存中的内容定义的。它可能是空的,它可能是一个有效的Tuple&lt;String, String&gt;[],纯属巧合(但不是你想使用的那个!),它可能是一个Dictionary&lt;int, List&lt;string&gt;&gt;,运行时现在认为实际上是一个Tuple&lt;String, String&gt;[](还有整个系统的类型安全性),它可能是decimal 结构的四分之一。 (在允许此类事情的语言中,它也可能是一个众所周知的值,此类语言的调试器在这些情况下精确设置,以帮助发现由它引起的错误)。

      这是我们可以得到的最接近没有值的属性的东西。请注意:

      1. 它仍然有一个值,只是没有一个有意义的值。
      2. 无论如何,我们都不允许在 C# 中执行此操作。

      【讨论】:

        猜你喜欢
        • 2018-10-03
        • 2013-01-18
        • 1970-01-01
        • 2010-12-12
        • 1970-01-01
        • 2013-09-17
        • 2013-05-24
        • 2011-02-13
        • 1970-01-01
        相关资源
        最近更新 更多