使用get vs property vs方法

时间:2009-03-23 23:26:12

标签: c#

如果我在一个类中有私有属性,我想知道在以下三种情况(内存使用,可用性,最佳实践等)之间的区别是什么:

class testClass
{
     private string myString1 = "hello";

     private string myString2 { get { return "hello"; } }

     private string myString3() { return "hello"; }
}

除了显然能够在myString1中设置值而不在myString2或myString3中设置值之外,我想知道更多关于它们在效率方面有何不同?

6 个答案:

答案 0 :(得分:8)

我尽可能遵循这些规则:

  • 字段应保密。
  • 属性应用于公开数据
  • 应该使用方法来执行操作

显然会出现一些情况,即每次性能下降都很重要,但总的来说,我会尝试遵循最佳实践,直到分析告诉您需要进行优化。

这里有一篇好文章:Why Properties Matter

答案 1 :(得分:5)

我个人更喜欢没有副作用的物品和明确的吸气剂,如果有动物计算的话。例如:

class User {
    private string username;

    public string Username {
        get { return username; }
        set { username = value; }
    }

    public Post GetLatestPost() {
        // query the database or whatever you do here.
    }
}

我见过的许多API似乎都是这样做的。希望有所帮助。

答案 2 :(得分:2)

所有这些方法在编译时都非常不同,尽管在使用方面非常相似。我将简要总结一下这些差异:

  1. 这是一个简单的私有实例变量。在引用时,它很容易变得最有效。

  2. 这是一个只读属性(即get但没有set访问器)。

  3. 这是一个普通的无参数函数。我怀疑你只是提供这些例子纯粹作为比较点,并意识到这样的功能是完全无用的(在几乎所有情况下都是私有属性)。布局(即一条线上的所有东西)也相当可怕。

  4. 与1相比,方法2和3的效率同样低,因为它们都涉及函数调用的开销。我不知道他们都编译到的CIL代码(也许其他人可以生成它),但它们肯定涉及更多的指令,而引用myString1应该只需要CIL中的单个指令。

    我不确定在不了解更多关于上下文的情况下,我可以对最佳实践做出非常有用的评论,但方法2(即私有财产)通常被认为是无用的。在我看来,第三种方法永远不应该被使用(它要求变成一种财产)。我认为你真正想要的只是一个普通的旧私有变量,所以一定要去做第一个声明。公共值应始终作为属性而不是类中的变量(即属性的私有/受保护的后备变量)进行访问,但这与您的问题略有不同。 (无论如何,你可以找到很多资源在快速搜索中讨论这个问题。)最后,请注意,如果你的“属性”是只读的(即在任何时候都没有修改),你真的想要使用常量,即private const string myString1 = "hello";

    希望这有助于澄清一些事情。

答案 3 :(得分:0)

这是一个很好的问题:

你有这个选择:

private string myString = "hi!";   //Private Field

public string MyString             //Property created to the private field
{
  get {return myString;}
}

public string myString {get; private set;}   //VS2008 automatic properties

public string getMyString()                  //Method Way
{
   return myString;
}

正如您所看到的,这个想法是相同的,而不是违反封装原则。使用您感觉更舒适的,所有这些都达到了目标,但我推荐物业方式或VIsual Studio 2008自动属性。

比方法更简洁明了。

希望这有帮助!

此致!!

答案 4 :(得分:0)

就最佳做法而言,

class testClass
{
   private string _myString;

   public string myString { get { return _myString; } set { _myString = value; } }

   public testClass()
   {
      myString = "Hello";  // Initial value.
   }
}

通常建议使用它来实现封装(隐藏内部状态,以便所有操作都通过方法/接口)。当然,制定者和吸气者通常都是方法本身。

在C#3.0中,您可以将以上内容替换为:

class testClass 
{    
  public string myString { get; set; }

  public testClass()
  {
      ...
  }
}

就效率而言,你真的应该考虑你的设计是否直接访问变量效率而不是属性。差异是如此之小(如果有的话)和最佳实践指南如此明确,以至于你只是担心效率。

答案 5 :(得分:-1)

以上关于设计,风格等的所有讨论都是有效的。但问题是关于表现。很容易测试。在每个invokations周围包含一些计时器,重复到int32.Max。 在我的机器上,下面的代码显示myString1要快得多。 (请注意,我必须更改类定义以使成员公开):

    private void button2_Click(object sender, EventArgs e)
    {
        //performance test
        testClass t = new testClass();
        System.Diagnostics.Stopwatch sw1 = new System.Diagnostics.Stopwatch();
        sw1.Start();
        for (int i = 0; i < int.MaxValue; i++)
        {
            string result = t.myString1;
        }
        sw1.Stop();

        System.Diagnostics.Stopwatch sw2 = new System.Diagnostics.Stopwatch();
        sw2.Start();
        for (int i = 0; i < int.MaxValue; i++)
        {
            string result = t.myString2;
        }
        sw2.Stop();

        System.Diagnostics.Stopwatch sw3 = new System.Diagnostics.Stopwatch();
        sw3.Start();
        for (int i = 0; i < int.MaxValue; i++)
        {
            string result = t.myString3();
        }
        sw3.Stop();
        MessageBox.Show(string.Format("Direct: {0}, Getter: {1}, Method: {2}"
            , sw1.ElapsedMilliseconds.ToString()
            , sw2.ElapsedMilliseconds.ToString()
            , sw3.ElapsedMilliseconds.ToString()));
    }


class testClass 
{ 
    public string myString1 = "hello";
    public string myString2 { get { return "hello"; } }
    public string myString3() { return "hello"; } 
}