何时以及为什么要使用C#访问器方法?

6

可能重复:
C# - 何时使用属性而不是函数

我正在尝试了解何时以及为什么要使用“getter”和“setter”。

请有人提供一些指导。

以下结构之间的区别是什么 - 请仅考虑访问器方法。

//EXAMPLE 1: simple accessor method 
private static bool _isInitialEditMapPageLoad;
public static bool isInitialEditMapPageLoad
{
    get {return _isInitialEditMapPageLoad;}
    set {_isInitialEditMapPageLoad = value;}
}

//EXAMPLE 2: accessor method with a conditional test
private static bool _isInitialEditMapPageLoad;
public static bool isInitialEditMapPageLoad
{
    get 
    {
        if (currentSession[isAuthorizedUseder] == null)
            return false;
        else
            return _isInitialEditMapPageLoad;    
    }
    set {isInitialEditMapPageLoad = value;} 
}


//EXAMPLE 3: just a get accessor method - is this the same as EXAMPLE 4?
private static bool _isInitialEditMapPageLoad = false;
public static bool isInitialEditMapPageLoad
{
    get {return _isInitialEditMapPageLoad;}
}


//EXAMPLE 4: simple method
private static bool _isInitialEditMapPageLoad = false; 
public static bool isInitialEditMapPageLoad
{
  return _isInitialEditMapPageLoad;     
}

6
你有一个栈溢出错误;第四个例子是不正确的。 - Gregoire
没看到,好发现。 - David
这些示例可能不是最好的,也不是我寻找的基础 - 对此我很抱歉。我真正想要的是关于何时使用和何时不使用访问器方法的解释。 - shawn deutch
获取器和设置器是用于添加方法功能以必要时操作类属性的吗? - shawn deutch
它们用于管理谁可以访问你的类存储的值,并管理这些交互的进行方式。你永远不应该公开暴露一个字段。如果在你正在处理的类之外的代码需要读取这个值,你应该为其提供一个getter方法。如果在你正在处理的类之外的代码需要编辑这个值,你应该为其提供一个setter方法。如果其他代码需要在任一情况下运行(验证等),请在属性的getter/setter中实现它。如果只需要简单访问,可以使用自动属性。 - PeterL
4个回答

8

您的getter/setter应该是您类的公共接口。作为一个经验法则,除了您希望外部类在类外部访问的内容之外,所有成员变量都应该是私有的,并且您永远不希望您的私有变量在类外部直接可访问。

以下是一个简单的例子。比如说您需要一个age变量的类。在这种情况下,您可以在setter中执行验证,而不需要让外部类知道该值已经被验证过。

class Person {
  int age = 0;

  public int Age {
    get { return age; }
    set { 
      //do validation
      if (valid) {
        age = value;
      }
      //Error conditions if you want them.
    }
  } 

  //More getters/setters
}

5

获取器/设置器的原因是保护类不会因为用户以无效的方式更改字段而被破坏,它们允许您在保持公开暴露的属性不变的情况下更改类的实现。

除非您需要某种验证或延迟加载属性,否则通常只需使用自动属性。

public string Name { get; set; }

3

1:这是一个简单的属性,可以像公共字段一样使用。如果您有理由向其他用户(即其他类)公开getset操作,并且不需要任何花哨的东西,那么这就是它。这也可以用“自动属性”来编写。

public static bool isInitialEditMapPageLoad {get;set;} // behaves just like example 1

自动属性的编写速度更快,而且在我看来比完整声明更易读(如果我看到带有后备字段的完整声明,我会认为其中有一些复杂性)。
这展示了使用属性的原因之一:使用某些逻辑返回值,而不是始终直接返回值。任何人都可以随时像公共字段一样设置此值。他们也可以随时获取该值,但有一个警告,即false表示这不是初始加载或用户未经授权,也就是说,在返回值之前执行了一些(简单的)逻辑。
对于只读取的外部代码来说,它的行为类似于公共字段-某人可以检索该值,但不能设置它。这本质上是一个对外部代码只读的值(不要与readonly关键字混淆)。
对我来说导致编译错误。假设它应该是一个方法声明,手动定义getter(就像Java中所做的那样),那么它类似于示例3。我认为还有其他问题使得它不完全相同,例如,如果您想将其转换为依赖项属性等。不幸的是,我的知识在这个领域里不足够。
作为一般规则,使用属性限制对类数据的访问。原则上,任何可以防止其他代码触及的东西都应该保持这种状态。实际上,您将希望能够设置类的值以更改其显示方式、修改所表示的数据等。使用属性来维护此交互的最大控制。
如果其他类需要查看您类中的某些内容,则需要公开getter,但不需要setter。这对于字段来说是不可能的,除非您使用Java编写自定义getter方法。它们还允许您在返回或设置数据之前执行计算或验证。例如,如果您有一些整数值应在某个范围内(该范围可以根据对象的状态而变化),则可以在setter中检查以确保满足此条件后才更新值。
尝试避免只将所有内容设置为自动属性的陷阱-这与使所有内容成为公共字段没有区别。尽可能保持所有内容私有。除非必要,否则不要使用getter,也不要使用setter,如果适当,setter应执行任何必要的小逻辑以验证输入是否正确。话虽如此,还要避免另一个陷阱:在getter/setter中放置大量代码。如果需要超过几行,那么您可能应该创建一个方法而不是属性,因为它可以向使用您代码的其他人提供更大的提示,即将发生一些重大事件。

2

像其他人提到的一样,当你希望对象成员对其他对象可用时,请使用getter/setter。

此外,如果你正在使用.NET 2.0或更高版本,则可以使用自动属性来提高代码的可读性。你的示例将类似于以下内容:

// example 1
public static bool IsInitialEditMapPageLoad { get; set; }

// example 3/4 - note that false is the default for bools
public static bool IsInitialEditMapPageLoad { get; private set; }

由于验证逻辑在这里,所以示例3可能会保持不变。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接