如果我在一个类中有私有属性,我想知道在以下三种情况(内存使用,可用性,最佳实践等)之间的区别是什么:
class testClass
{
private string myString1 = "hello";
private string myString2 { get { return "hello"; } }
private string myString3() { return "hello"; }
}
除了显然能够在myString1中设置值而不在myString2或myString3中设置值之外,我想知道更多关于它们在效率方面有何不同?
答案 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)
所有这些方法在编译时都非常不同,尽管在使用方面非常相似。我将简要总结一下这些差异:
这是一个简单的私有实例变量。在引用时,它很容易变得最有效。
这是一个只读属性(即get但没有set访问器)。
这是一个普通的无参数函数。我怀疑你只是提供这些例子纯粹作为比较点,并意识到这样的功能是完全无用的(在几乎所有情况下都是私有属性)。布局(即一条线上的所有东西)也相当可怕。
与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"; }
}