在下面的setter中,我可以直接或通过getter访问属性支持字段。是否存在一个人比另一个更受欢迎的情景?
public string Name {
get { return this.name; }
set {
if (value == this.name) return;
// or
// if (value == this.Name) return;
// ?
this.name = value;
NameChanged.Raise(this, this.name);
// or
// NameChanged.Raise(this, this.Name);
// ?
}
}
有一个相关的问题。你会如何在c-tor中初始化属性?
public MyClass(string name) { this.name = name; }
// or
public MyClass(string name) { Name = name; }
我使用this.name
,因为在构造时实例可能处于无效/不稳定/未定义状态,因此Name-setter验证可能会错误地失败。还有其他意见吗?
答案 0 :(得分:3)
我会说“Name = name”更正确,因为如果你要将“name”属性声明为virtual,那么有人可能会覆盖你的属性行为,但你的构造函数仍会绕过它们的逻辑。 /击>
此外,属性可以封装行为,例如提升更改事件,您不应绕过这些行为。在构造对象之前,任何用户都无法为事件添加处理程序。因此,如果在具有外部事件的构造函数中进行设置,则不会引发该设置。
修改
请参阅下面的评论,了解为什么虚拟是一个糟糕的例子。
答案 1 :(得分:2)
我个人解决这个问题的方法是
只有在使用此限定符时才会导致不正确的行为或编译错误。
我更喜欢在这个限定符的绝对值中使我的代码可读。如果没有这个限定符它是不可读的,我会努力将代码更改为可读。
答案 2 :(得分:2)
在这种情况下,语法之间的区别在于,在一种情况下,getter / setter被调用,而在另一种情况下,它们不会。正确的吗?
我认为最好使用Name而不是this.name。这样,只有getter / setter可以访问“不受保护”的变量,并且你可以确认任何关于这个值的不变量,只能在getter和setter而不是整个类中查找 。
答案 3 :(得分:1)
我同意其他人的意见;你通常想要使用该属性。这样做的原因是你将获得随之而来的逻辑。例如,在WPF中,如果不使用该属性而是使用字段,则不会触发PropertyChanged事件,这意味着绑定到该属性的任何控件都不会更新。当然,你不能在属性中调用属性,否则你最终会出现堆栈溢出。
也就是说,当你想要完全避免这种逻辑时,是次,并且偶尔变量初始化就属于这种情况。在这种情况下,您想要使用该字段。
答案 4 :(得分:1)
我个人的意见是优先使用该属性,除非这导致不正确的行为。它归结为使用属性表明了对类的语义和API设计的承诺。
显然有时会出现这个规则的例外情况......有时候,“属性”意味着与支持字段的值不同(在您的示例中,属性会引发事件)。如果内部使用明确需要避免属性的语义(您不希望触发事件),那么支持字段是正确的“第二选择”。
在一个不相关的说明中,无论好坏,Microsoft StyleCop应用程序特别喜欢使用'this'前缀访问私有字段的约定来区分对局部变量和类字段的访问(而不是前缀这样的作为'_
'或'm_
'或其变体......具有讽刺意味的是传统.NET框架代码中使用的约定。)
答案 5 :(得分:1)
如果您不小心,访问该属性中的字段可能会导致溢出。我总是访问该物业以避免这些潜在的情况。
答案 6 :(得分:0)
在下面的setter中,我可以直接或通过getter访问属性支持字段?是否存在一个人比另一个更受欢迎的情景?
仅在与范围
中的其他变量发生冲突时使用它有一个相关的问题 - 如何在c-tor中初始化属性?
如果您有房产,请使用房产
答案 7 :(得分:0)
我不想提出PropertyChanged事件,而是访问字段而不是属性。但是,在构造函数中,您并不真正关心提升该事件,因为您确定没有人订阅该事件...
答案 8 :(得分:0)
我的建议是,如果您有权访问该字段,并且该字段不需要特殊逻辑。一个例子:
private int width;
public int Width
{
get
{
return width;
}
set
{
if (value < 0)
throw new InvalidArgumentException("Mass cannot be below 0");
width = value;
}
}
在这种情况下,您不希望访问该字段,因为您(可能)无法保证您设置的值高于0。 但是,如果您有以下属性:
public int Height { get; set; }
然后在可能的情况下访问该字段可能是个好主意。