C# 属性显式设置与覆盖获取
C# property explicit set versus override get
简而言之:编写基本 class 属性,我们更喜欢显式 set
方法还是重写 get
方法?
我的主页有一个基础 class。它实现了几个"features";一些实例可能想要禁用该功能,这在设计时是已知的(即它不会改变)。基础 class 看起来像这样:
public class MyPage : System.Web.UI.Page
{
void Method()
{
if (Feature1)
DoSomething1();
}
}
问题是:以下两种定义 Feature1
属性的方法中哪一种是首选:
// In MyPage class
private bool _feature1 = true;
protected bool Feature1
{
get { return _feature1; }
set { _feature1 = value; }
}
// In Derived page class, somewhere early
Feature1 = false;
对比:
// In MyPage class
protected virtual bool Feature1
{
get { return true; }
}
// In Derived page class
protected override bool Feature1
{
get { return false; }
}
在第一种情况下,该属性具有显式 set
供派生 Page 调用;在第二种情况下,该属性没有 set
,而是允许派生的 Page 覆盖 get
。我们有偏好吗?
与我的 Pages 相比,此选择适用于更一般的 C# 案例,但它表明我在某些方面受到限制(例如,我没有做 new
,我不负责构造函数, ...)
使用自动 属性 并在构造函数中设置值。
protected bool Feature1 { get; set; }
// Your Constructor
public YourClassName(bool featureState)
{
Feature1 = featureState;
}
最好也覆盖 set
。由于它在派生 class 中没有功能,您或其他人可能想设置在这种情况下无效的值,然后在几天或几周后您想知道为什么它设置 Feature1
不是按需工作。所以如果有人试图设置它,你最好抛出一个异常:
override bool Feature1
{
get { return true; }
set { throw new InvalidOperationException("In this implementation 'Feature1' is read-only."); }
}
示例:
class Program
{
static void Main(string[] args)
{
bool baseFeature1a = new Base1().Feature1; // false
bool baseFeature1b = (new Derived1() as Base1).Feature1; // true
bool baseFeature2a = new Base1().Feature2; // false
bool baseFeature2b = (new Derived1() as Base1).Feature2; // true
}
}
class Base1
{
private bool feature2 = false;
public virtual bool Feature1
{
get { return false; }
}
public virtual bool Feature2
{
get { return feature2; }
protected set { feature2 = value; }
}
}
class Derived1 : Base1
{
public Derived1()
{
Feature2 = true;
}
public override bool Feature1
{
get { return true; }
}
}
根据您的描述,听起来您确实打算将其设为只读字段。
在这种情况下,只定义 属性 的 get
一半,并在派生的 类 中覆盖它是合适的。
这也有一个 compile-time 错误的好处,而不是 运行-time 错误,如果有人尝试设置它。
当然,如果它不是应该是只读的,那么你需要实现setter。
简而言之:编写基本 class 属性,我们更喜欢显式 set
方法还是重写 get
方法?
我的主页有一个基础 class。它实现了几个"features";一些实例可能想要禁用该功能,这在设计时是已知的(即它不会改变)。基础 class 看起来像这样:
public class MyPage : System.Web.UI.Page
{
void Method()
{
if (Feature1)
DoSomething1();
}
}
问题是:以下两种定义 Feature1
属性的方法中哪一种是首选:
// In MyPage class
private bool _feature1 = true;
protected bool Feature1
{
get { return _feature1; }
set { _feature1 = value; }
}
// In Derived page class, somewhere early
Feature1 = false;
对比:
// In MyPage class
protected virtual bool Feature1
{
get { return true; }
}
// In Derived page class
protected override bool Feature1
{
get { return false; }
}
在第一种情况下,该属性具有显式 set
供派生 Page 调用;在第二种情况下,该属性没有 set
,而是允许派生的 Page 覆盖 get
。我们有偏好吗?
与我的 Pages 相比,此选择适用于更一般的 C# 案例,但它表明我在某些方面受到限制(例如,我没有做 new
,我不负责构造函数, ...)
使用自动 属性 并在构造函数中设置值。
protected bool Feature1 { get; set; }
// Your Constructor
public YourClassName(bool featureState)
{
Feature1 = featureState;
}
最好也覆盖 set
。由于它在派生 class 中没有功能,您或其他人可能想设置在这种情况下无效的值,然后在几天或几周后您想知道为什么它设置 Feature1
不是按需工作。所以如果有人试图设置它,你最好抛出一个异常:
override bool Feature1
{
get { return true; }
set { throw new InvalidOperationException("In this implementation 'Feature1' is read-only."); }
}
示例:
class Program
{
static void Main(string[] args)
{
bool baseFeature1a = new Base1().Feature1; // false
bool baseFeature1b = (new Derived1() as Base1).Feature1; // true
bool baseFeature2a = new Base1().Feature2; // false
bool baseFeature2b = (new Derived1() as Base1).Feature2; // true
}
}
class Base1
{
private bool feature2 = false;
public virtual bool Feature1
{
get { return false; }
}
public virtual bool Feature2
{
get { return feature2; }
protected set { feature2 = value; }
}
}
class Derived1 : Base1
{
public Derived1()
{
Feature2 = true;
}
public override bool Feature1
{
get { return true; }
}
}
根据您的描述,听起来您确实打算将其设为只读字段。
在这种情况下,只定义 属性 的 get
一半,并在派生的 类 中覆盖它是合适的。
这也有一个 compile-time 错误的好处,而不是 运行-time 错误,如果有人尝试设置它。
当然,如果它不是应该是只读的,那么你需要实现setter。