为啥我应该在属性访问器中使用私有变量?

Posted

技术标签:

【中文标题】为啥我应该在属性访问器中使用私有变量?【英文标题】:Why should I use a private variable in a property accessor?为什么我应该在属性访问器中使用私有变量? 【发布时间】:2010-12-30 00:17:21 【问题描述】:

对不起,如果我是菜鸟,我有这个疑问,为什么我们要使用私有变量并使用属性来设置它们?

为什么我们不能只使用properites?

我说的是这样的情况

private string _testVariable;

public string MyProperty

    get  return _testVariable;
    set _testVariable = value;

我正在考虑简单地使用

public string MyProperty  get; set;  

为什么是多余的私有变量?这两种策略有什么不同吗?任何人都可以请对此有所了解。

谢谢

【问题讨论】:

对不起,我只是从我的第一个 sn-p 复制..忘记在第二个中删除..谢谢 :) 可以问菜鸟问题。 谢谢,我是软件开发新手,但我想学习 :) 【参考方案1】:

你给出的第二个例子:

public string MyProperty  get; set; 

仅在 .Net 框架的更高版本中可用(我相信是 v3.0 及更高版本)

第一个示例允许您在 return 和赋值语句上设置断点,从而导致您的调试器在分配/读取属性时中断。

【讨论】:

不,您可以使用 .Net 2.0 作为目标。但是你需要一个 C# 3 编译器。【参考方案2】:

第一个代码片段允许您修改一些私有类状态。在属性中包装私有状态很好,因为它隐藏了实现。稍后您可以更改实现,并且属性(外部接口)可能保持不变。

例如,假设您没有在 setter 中设置单个字符串,而是将字符串设置在某种私有存储中。您将其写入文件,或将其写入共享内存。或者,也许您只计算字符串的哈希值,而根本不存储它,就像您可能使用密码所做的那样。

第二个代码片段中的自动属性与私有变量完全无关。自动属性设计,就像第一个片段中使用的显式属性设计一样,允许将来进行修改。例如,作为修改的一部分,您可以从自动属性转换为显式实现的属性。

【讨论】:

【参考方案3】:

您的示例在语义上是相同的。简洁的属性声明语法(只有 get; set; )是 C# 3.0 中可用的快捷方式。编译器实际上创建了一个私有后备变量和一个简单的 getter 和 setter,就像您的第一个示例一样。

如果您所做的只是创建一个 getter 和 setter(当两者发生时实际上什么都没有发生),那么简洁的语法是一个不错的选择。如果您在设置值时必须执行任何其他操作(例如重绘控件),则需要完整的语法。

【讨论】:

如果您不确定是否需要使用额外的逻辑,一件好事是,如果您使用速记,您以后可以随时递增它,而外部代码不会注意到它是一次只是一个美化的变量。【参考方案4】:

属性基本上是一个字段的包装。这个包装器允许使用来自外部世界的变量。在 C#3.0 中,您可以简单地声明一个属性,如 public string MyProperty get; set; 编译器会自动声明一个私有变量并为其设置方法。如果您需要在声明属性的类中执行任何计算,那么您应该使用私有字段。

【讨论】:

【参考方案5】:

有时您在第一次编写代码时不知道以后是否会添加更多需要使用私有变量的代码。当然,如果需要,您可以稍后添加它。我只是自动创建了私有变量,假设以后会用到。

这可能与大型企业应用程序或快速发展的应用程序(敏捷)更相关,因为在初始编码期间可能不知道完整的实现。

【讨论】:

从自动属性更改为由显式私有变量支持的属性相当容易且不会中断。我不明白为什么你会为了以后有人可能需要它而不必要地混乱你的代码。您是否也对代码的其他部分执行此操作? 不,只是属性。总是创建私有变量给了我一个可预测的代码状态。如果您使用代码生成器来创建所有属性,这样做会更容易:) 但是您的观点很好。【参考方案6】:

为什么是多余的私有变量?是 这两种策略有什么不同?能够 任何人都请点亮 这个。

如果你所做的只是读/写一个变量,那么没有。否则,您需要私有变量的原因有两个:

数据验证

// Data validation
public class IntWrapper

    private int _value;
    public int Value
    
        get  return _value; 
        set
        
            if (value < 0)  throw new Exception("Value must be >= 0"); 
            _value = value;
        
    

Getter/setter 封装了底层数据存储

public class StringBuffer

    List<char> chars = new List<char>();

    // Wraps up an underlying data store
    public string Value
    
        get  return new String(chars.ToArray()); 
        set  chars = new List<char>(value.ToCharArray()); 
    

    public void Write(string s)  Write(chars.Count, s); 

    public void Write(int index, string s)
    
        if (index > chars.Count)  throw new Exception("Out of Range"); 
        foreach(char c in s)
        
            if (index < chars.Count)  chars[index] = c; 
            else  chars.Add(c); 
            index++;
        
    

【讨论】:

【参考方案7】:

捣碎, 我们都必须从某个地方开始!你用这个 ex 询问了私有变量与属性:

private string _testVariable;

public string MyProperty

    get  return _testVariable;
    set _testVariable = value;


-or-

public string MyProperty  get; set; 

您是否考虑过:

public string MyProperty  get; private set; 

您可以将范围应用于属性 getters/setters 。 . . .酷的东西。哦耶 。 . .在定义类中(如在构造函数中)使用这种类型的属性时,在它前面加上“this”。 - 所以分配看起来像'this.MyProperty = "An Assigned String";'。这使您的意图更加更加清晰。 . .

【讨论】:

【参考方案8】:

这与 C# 语言无关,而与应用程序有关。

使用属性的一个原因是它在许多框架中被视为“特殊”。 例如,Silverlight 和 WPF 将绑定到属性而不是字段

【讨论】:

【参考方案9】:

我讨厌不需要的后备变量,这会导致比必要的更复杂。

显然,如果您需要在 getter 或 setter 中做一些特殊的事情,那么应该使用完整的语义形式而不是糖。

我还喜欢使用属性作为调试属性设置或使用方式的一种方法,有时由于反射,这并不那么明显,这也是我喜欢使用它们的原因之一。

当支持变量可能通过它自身的属性或支持变量在类内部访问并且没有告诉编码器正确的访问方式时,我发现尝试调试代码令人沮丧。

您可以在内部访问支持变量以及属性,那么哪种方法是正确的?不明显……

【讨论】:

以上是关于为啥我应该在属性访问器中使用私有变量?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我可以在复制构造函数中访问私有变量?

为啥我不能在 main 方法中调用私有变量?

为啥我可以从 main 方法访问私有变量?

为啥我的函数不能访问它所在类的私有变量 INSIDE?

为啥我能够从在同一对象的另一个实例上调用的方法访问一个实例的私有实例变量? [复制]

Python私有变量与私有方法