SET如何在C#中使用属性?

时间:2010-05-07 12:22:20

标签: c#

我想知道 set 如何在属性中工作,而不仅仅是设置私有成员变量的值。假设我的班级中有一位私人会员( private int myInt )。

例如,我可以确保返回的值不是负数

get
{
  if(myInt < 0)
    myInt = 0;
  return myInt;
}

使用 SET ,我所能做的就是像这样影响私有变量

set { myInt = value; }

我在任何一本书中都没有看到我能做的更多。如果在影响myInt的值之前我不想做一些操作怎么样?假设:如果值为负,则将0设置为myInt。

set
{
  //Check if the value is non-negative, otherwise affect the 0 to myInt
}

感谢您的帮助

7 个答案:

答案 0 :(得分:9)

你可以做你想做的事。

没有什么可以阻止你:

set
{
    if (value < 0)
        myInt = 0;
    else
        myInt = value;
}

(或更紧凑的版本)

这就是设置者和吸气剂的目的。

如果值超出范围,您可以添加日志记录,调试断言甚至引发异常。

<强> BUT

您的Setters和Getters的用户不会期望他们进行“大量”处理或有任何副作用。所以他们应该只影响他们的支持变量而不是处理1000个文本文件(作为例子)。与数据库的连接很好,但是如果要获得大量数据,则应该使用显式函数替换Get。

另外,请注意@StingyJack在答案中所说的内容。

答案 1 :(得分:7)

您可以在“设置”中执行任何操作。你问的具体例子是:

set { 
  // Silently set to a more correct value
  myInt = value < 0 ? 0 : value; 
}

set { 
  // Always return error to caller
  if (value < 0) {
     throw new ArgumentException("value", "value cannot be negative.")
  }
  myInt = value; 
}

set { 
  // When debugging, warn the developer, in release adjust value silently
  Debug.Assert(value >= 0, "Value should 0 or larger");
  myInt = value < 0 ? 0 : value; 
}

答案 2 :(得分:5)

属性编译为常规方法,因此您可以在set语句中执行任何操作。理论上,您甚至不需要访问单个成员变量或使用value关键字。尽管如此,使用setter而不是设置成员变量通常被认为是不好的做法。

答案 3 :(得分:4)

你可以这样做:

set { myInt = value < 0 ? 0 : value; }

无论你想要什么样的逻辑,你都可以像其他任何value一样使用Int ......或者你的财产是什么类型,value就是那种类型,做你将用它做什么:)

答案 4 :(得分:2)

我可以想到几个原因 - 它更常见于setter简单,但是setter在更复杂的情况下非常有用:

底层存储类型与外露类型

不同

当您在某个其他对象周围创建包装并希望隐藏复杂性

时,可能就是这种情况

有时转换可能很简单(double to int等...)有时它可能更复杂(某些强类型对象的Xml)。

class ThingWrapper
{
    public Thing Thing {get; set;}

    public int SomeProperty
    {
        get
        {
            return int.Parse(this.Thing.SomeProperty);
        }
        set
        {
            Thing.SomeProperty = value.ToString();
        }
    }
}

您希望阻止属性更改

也许你有某种对象暴露了一个在另一个线程中运行的长时间运行的后台任务,你希望阻止用户在该任务运行时更改属性。

您需要从事件中分离

您可能有一些对象公开您订阅的事件,并且您还希望能够设置该对象(由于某种原因)。在这种情况下,您需要确保从旧对象中分离事件处理程序并重新连接到新对象。

答案 5 :(得分:1)

这样的财产:

public int SomeValue
{
    get { return _SomeValue; }
    set { _SomeValue = this; }
}

基本上是这样的:

public int SomeValue { get; set; }

public int get_SomeValue()
{
    return _SomeValue;
}

public void set_SomeValue(int value)
{
    _SomeValue = value;
}

所以你可以放入两个类似的方法,这对两个属性访问器方法都有效。

答案 6 :(得分:0)

就像所有这些答案所说的那样,你可以在一套中做任何你想做的事情。这并不意味着你应该......

采取以下有点人为的例子

Public Class MyClass

 Private m_myValue as String

 Public Property MyValue as String
  Get
   If String.IsNullOrEmpty(m_myValue) Then
    Return String.Empty
   Else
    Return m_myValue
   End If
  End Get
  Set (Value as String)
   If String.IsNull(m_myValue) = False Then
    m_myValue = Value
   End If
  End Set
 End Property

 Public Function GetLengthOfMyValue() as Integer
  Return m_myValue.Length
 End Function

End Class

如果您要运行以下代码段,_len2调用会给您一个例外,因为它没有扩展属性所提供的相同空值保护。

Dim _mc as New MyClass()
Dim _len1 as Integer = _mc.MyValue.Length
Dim _len2 as Integer = _mc.GetLengthOfMyValue()

现在,正如我所说,这是一个人为的例子,但我确实看到它在实践中经常发生,并且在许多情况下,它会增加行为的细微差异,从而导致错误或其他意外后果。

  • 该功能是否应该使用该属性?您的偏好是什么(您的组织编码标准已经为您决定了)?
  • 有没有更好的方法可以在没有代码重复的情况下完成您想要的任务?

在使用此模式之前,您可能需要考虑一下。