我们是否需要C#属性中的支持字段?

时间:2016-05-25 08:40:10

标签: c# properties

注意:这是有关自动实施属性的问题。自动实现的属性是关于getter和setter中没有逻辑的属性,而我在代码中非常清楚地表明存在一些逻辑。这不是duplicate,因为问题确实不同,答案也是如此。但是,我会在代码中插入一些特定的逻辑,以便更清楚。

我看到很多这个:

private int _age;
public object Age
{
    get
    {
        if(user.IsAuthorized)
        {
            return _age;
        }
    }
    set
    {
        if(value > 0 && value < 120)
        {
            _backingField = value;
        }
        else
        {
            Console.Write("Non-valid age");
        }
    }
}

但为什么我们需要支持领域?为什么不返回Property本身,如下所示?

public object Age
{
    get
    {
        if(user.IsAuthorized)
        {
            return Age;
        }
    }
    set
    {
        if(value > 0 && value < 120)
        {
            Age = value;
        }
        else
        {
            Console.Write("Non-valid age");
        }
    }
}

4 个答案:

答案 0 :(得分:6)

好吧,返回属性本身会导致 Stack Overflow 异常:

public object Property 
{
    get
    {
        return Property;
    }
    set
    {
        Property = value;
    }
}

想象

  MyObject o = new MyObject();

  // cause Stack Overflow exception
  o.Property = null;

很容易理解为什么:

  1. 设置Property = null来电set
  2. 致电Property = value;,后者又拨打set
  3. 致电Property = value; ......等等。
  4. 因此,如果属性存储某个值,该值应存储在字段中(您需要一个字段),我们无法使用属性存储本身。如果您想缩短代码,请将其设置为此(自动属性):

      public object Property { 
        get; // let .Net create a backing field for you
        set;
      }
    

答案 1 :(得分:1)

该属性实际上只有两种隐藏方法:get_Propertyset_Property。如果从Property的getter返回Property,实际上会导致无限递归循环,这将导致堆栈溢出异常:您正在从方法{{调用方法get_Property 1}},反过来调用get_Property等等。

编辑:正如评论中所阐明的那样,该属性只是两种方法,仅此而已。没有什么可以保存数据;支持字段实际上包含数据。如果要将get_Property存储为实例中的数据,则必须保存该数据,这就是您需要支持字段的原因。

自动属性会自动创建支持字段:

Age

在所有其他情况下,该属性只有两种方法,所有数据存储都是独立的,您必须自己处理。

答案 2 :(得分:1)

每次将值设置为Property时,都会调用set-block。所以在你的例子中它将是:

Property = 10
-- Inside set: Property = Set
----- Called again set: Property = Set
----------- And so on and so o

名词

但是,您可以执行以下操作:

    public int Property
    {
        get;
        set;
    }

答案 3 :(得分:1)

public object Property
{
    get
    {
        return Property;
    }
    set
    {
        Property = value;
    }
}

这将返回属性本身并最终以递归循环结束,堆栈溢出。因此,您希望返回另一个对象,例如_property。