为什么要为类中的私有成员创建公共包装器?
本文关键字:创建 包装 成员 为什么 | 更新日期: 2023-09-27 18:18:28
我一直有这个问题,但到目前为止我一直盲目地跟随。
这是一段示例代码:
为什么这样做:
public class EmployeeInfo
{
int _EmpNo;
public virtual int EmpNo
{
get { return _EmpNo; }
set { _EmpNo = value; }
}
string _EmpName;
public virtual string EmpName
{
get { return _EmpName; }
set { _EmpName = value; }
}
}
在获取/设置期间没有任何其他操作,例如计算或验证?
这就够了吗?
public class EmployeeInfo
{
public int EmpNo { get; set; }
public string EmpName { get; set; }
}
另外,为什么公共成员包装器是virtual
?
自从c# 3.0中添加了自动实现的属性后,真的没有理由这么做。它可能是未更改的遗留代码,旧习惯,或者与c# 3之前的代码保持一致。为什么这样做?
这就够了吗?
No -你已经将virtual
属性转换为非虚拟。所以它们不是完全等价的。
对应的是
public class EmployeeInfo
{
public virtual int EmpNo { get; set; }
public virtual string EmpName { get; set; }
}
同样,为什么public成员包装器是virtual ?
以便派生类可以覆盖属性的逻辑—添加验证,更改通知等。
缩写形式在什么时候真正产生影响?
当后备字段被类的内部代码引用时(可以在编译时检测到),或者当它们被反射访问时(只有在运行时才能检测到,或者通过静态代码分析)。
一个"自动实现"的属性实际上得到一个由编译器创建的后备字段,所以在这个意义上,如果后备字段被引用的唯一地方是在属性代码中,它们是等价的。
你有两个问题。首先是将属性更改为自动实现的属性,它们应该是相等的,但是你删除了virtual
关键字,这使得它们不同。
那么,virtual
是什么?该关键字将允许派生类覆盖上述属性的get/set
。
参见:virtual c#
virtual关键字用于修改方法、属性、索引器或参数事件声明,并允许在派生类中重写类 .
你的类与自动实现属性将是相等的,如果你有:
public class EmployeeInfo
{
public virtual int EmpNo { get; set; }
public virtual string EmpName { get; set; }
}
之后,你可以重写一个属性,让另一个属性保持父属性的行为,比如:
public class ManagerInfo : EmployeeInfo
{
private int _EmpNo;
public override int EmpNo
{
get { return _EmpNo; }
set
{
if (value < 100) throw new Exception("EmpNo for manager must be greater than 100");
_EmpNo = value;
}
}
}
取决于您是否想要公开查看该字段,
如果你只打算在声明类中使用字段,那么你不需要将其包装在属性中,只有当你需要公开或在继承树中公开它时,你才应该使用属性
public string EmpName { get; set; }
只是编译器
的快捷方式private string _EmpName;
public string EmpName {
get{ return _EmpName;}
set(_EmpName = value; }
}
它们在功能上相同。然而,有一些事情是快捷方式不允许你做的,例如,你想在属性改变时引发一个事件。
中还使用了Virtual,这是一个继承修饰符Virtual指示代码需要向下查看继承树以寻找更新的实现。所以在
class A
{
public string Data
{
get{return "A";}
}
public virtual string VData
{
get{return "A";}
}
}
class B:A
{
public new string Data
{
get{return "B";}
}
public override string VData
{
get{return "B";}
}
}
那么如果你做了
A obj = new B();
obj.Data; //return A
obj.VData; //return B
代码如下:
$type _$var;
public virtual $type $var
{
get { return _$var; }
set { _$var = value; }
}
是使用工具、模板或代码片段生成的。由于习惯几乎没有改变,工具、模板和代码片段几乎没有更新,我猜它们是在自动实现属性(public $type $var { get; set; }
)引入c#语言之前创建的。
对于您所展示的代码,使用等效的
是完全有效的:public virtual $type $var { get; set; }
因为你可以覆盖自动实现的属性,并添加一个支持字段,验证和任何必要的
展开表单是传统的方式:
public class MyClass
{
int _myInt;
virtual public int MyProperty
{
get
{
return _myInt;
}
set
{
_myInt = value;
}
}
}
然而,较短的形式称为"auto properties",在c# 3.0中引入。
public class MyClass
{
virtual public int MyProperty { get; set; }
}
这些代码块是等价的。这是保持代码简洁的好方法。
需要考虑的一件事:您不能使内部变量protected
具有自动属性,因此,如果您创建了一个派生类并将override
创建为您的属性,则需要使用base.MyProperty
来访问它,或者使用扩展形式