代码之家  ›  专栏  ›  技术社区  ›  Juri

获取方法或私有属性?

  •  1
  • Juri  · 技术社区  · 15 年前

    这只是一个品味问题,但我想听听你的一些看法(这也是为什么这个问题被标为主观的原因)。

    如果我有财产,比如

    private string _Text;
    public string Text;
    get
    {
       object tmp = ViewState["Text"];
       if (tmp != null)
          _Text = Convert.ToString(tmp);
       return _Text;
    }
    set
    {
       ViewState.Add("Text", value);
    }
    

    现在,这个属性可以由程序员通过设置一些自定义文本来指定。然后将其映射到用户界面上的某个控件。但是,在默认情况下,控件的文本来自预定义的资源文件。因此,在内部以更好的方式处理这一问题,我有一个中心点,在这里我检查用户是否指定了“文本”属性(上面),如果指定了,那么使用该数据,否则依赖于资源文件中的默认值。

    那么你会采取什么方法呢?我有两个选择:

    private string ResolvedText
    {
       get
       {
          if(!string.IsNullOrEmpty(Text))
             return Text;
          else
             //return the one from the resource file
       }
    }
    

    或者把所有东西都放在一个方法里

    public string GetResolvedText()
    {
       if(!string.IsNullOrEmpty(Text))
          return Text;
       else
          //return the one from the resource file   
    }
    

    这个问题对你来说可能听起来很愚蠢,因为它真的是一个微小的区别。但我想知道这方面是否有一些惯例。

    谢谢

    5 回复  |  直到 15 年前
        1
  •  3
  •   Keith    15 年前

    我发现这里最好的一般规则是:如果两次调用操作会导致多个资源调用或不同的行为-使用一个方法。

    因此,在您的示例中,如果属性缓存以下内容,则可以使用它:

    public string ResolvedText
    {
       get { return Text ?? (Text = GetResolvedText()); }
    }
    

    但是,该方法不需要-用户希望它是一个更密集的操作:

    public string GetResolvedText()
    {
       //return the one from the resource file   
    }
    

    设计问题是您希望如何使用这个类?

    将调用一个属性,就好像它是一个“廉价”操作:

    if( myInstance.ResolvedText != null && 
        myInstance.ResolvedText.Length > 5 )
        Response.Write( myInstance.ResolvedText );
    

    方法提示开发人员,他们应该尽可能少地调用它:

    string resolvedText = myInstance.GetResolvedText();
    
    if( resolvedText != null && 
        resolvedText.Length > 5 )
        Response.Write( resolvedText );
    

    就我个人而言,我更喜欢保持临时类的简单性,因此在绝大多数情况下,我将使用方法模型。

    因为这是一个相当标准的约定,所以您应该避免不缓存的属性和这样做的方法。

        2
  •  6
  •   Steve Gilham    15 年前

    就我个人而言,我将获取getResolvedText方法的主体,并在属性中使用它,因此:

    private string _Text;
    public string Text
    {
       get
       {
         if(string.IsNullOrEmpty(_Text))
            //return the one from the resource file  
         else
            return _Text;
       }
    
       set
       {
          _Text = value;
       }
    }
    

    这将把管理字符串的所有责任都放在一个地方。类本身可以访问 _Text 内部,如果它需要原始值。

        3
  •  2
  •   Fredrik Mörk    15 年前

    我将把它作为一个属性来保存,因为它表示一个不需要很多计算就可以检索的值。

        4
  •  0
  •   Clement Herreman    15 年前

    对我来说,如果getter不能抛出异常或空/无效值,它应该是一个属性。这就是属性的作用。

    但是,如果你做一些复杂的事情,如果必须是一个函数getter。显然,这里只有1个if,所以我将使用一个属性。

        5
  •  0
  •   Sklivvz    15 年前

    将您的示例和Steve的答案重新组合在一起,再加上一些缓存,很明显,资源值应该只读取一次,因为它永远不会更改,并且根据合同,我们必须尽快从属性返回值:

    private static string ResourceText;
    
    static [constructor]
    {
        ResourceText = //get resource;
    }
    
    private string text;
    public string Text;
    get
    {
       string tmp = (string)ViewState["Text"];
       if (!String.IsNullOrEmpty(tmp))
          text = tmp;
       else
          text = ResourceText;
       return text;
    }
    set
    {
       ViewState.Add("Text", value);
       // Note: passing null or empty strings will not work.
    }