我一直有这个问题,但到目前为止,我一直盲目跟进。
这是一段示例代码:
为什么这样做:
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
为公共成员包装器?
答案 0 :(得分:5)
为什么这样?
由于在C#3.0中添加了自动实现的属性,因此没有理由。它可能是遗留代码,没有改变,旧习惯,或与C#3前代码保持一致。
这样就够了吗?
不 - 您已将virtual
属性转换为非虚拟属性。所以它们并不完全等同。
等价物是
public class EmployeeInfo
{
public virtual int EmpNo { get; set; }
public virtual string EmpName { get; set; }
}
另外,为什么虚拟公共成员包装器?
这样派生类可以覆盖属性的逻辑 - 添加验证,更改通知等。
缩短的表格何时会产生影响?
当类的内部代码(可以在编译时检测到)或通过反射访问它们(在运行时无法检测到,或通过静态代码分析)访问后备字段时)。
“自动实现”属性实际上获得了编译器创建的支持字段,因此在这种意义上,如果引用支持字段的唯一位置是在属性代码中,则它们是等效的。
答案 1 :(得分:3)
你有两个问题。首先是将属性更改为auto implemented properties,它们应该相同,但您删除了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;
}
}
}
答案 2 :(得分:2)
取决于您是否要公开查看该字段,
如果你只想在声明类中使用该字段,那么你不需要将它包装在一个属性中,只有当你需要公开它或者你应该拥有属性的继承树时才将它公开
public string EmpName { get; set; }
只是编译器的捷径
private string _EmpName;
public string EmpName {
get{ return _EmpName;}
set(_EmpName = value; }
}
它们在功能上完全相同。
但是,有些事情可以让捷径不让你做,例如你想在房产改变时举起一个事件。
还有你使用Virtual这是一个继承修饰符 虚拟指示它需要查看DOWN继承树的代码以获得更新的实现。 所以在
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
答案 3 :(得分:1)
看起来像这种形式的代码:
$type _$var;
public virtual $type $var
{
get { return _$var; }
set { _$var = value; }
}
是使用工具,模板或代码段生成的。由于习惯几乎没有变化,工具,模板和片段几乎没有得到更新,我想它们是在自动实现的属性(public $type $var { get; set; }
)引入C#语言之前创建的。
对于您显示的代码,拥有等效代码完全有效:
public virtual $type $var { get; set; }
您可以覆盖自动实现的属性并添加支持字段,验证以及必要时的任何内容。
答案 4 :(得分:0)
扩展形式是传统方式:
public class MyClass
{
int _myInt;
virtual public int MyProperty
{
get
{
return _myInt;
}
set
{
_myInt = value;
}
}
}
然而,较短的形式被称为&#34;自动属性&#34;,在C#3.0中引入。
public class MyClass
{
virtual public int MyProperty { get; set; }
}
这些代码块是等效的。这是保持代码简洁的好方法。
要考虑的一件事:您无法使用自动属性制作内部变量protected
,因此如果您创建了一个派生类并且override
属性,那么您就可以了需要使用base.MyProperty
来访问它,或使用展开的表单。