我最近学到了c#,所以当我学会写属性时,我被教会这样做:
public string Name { get; set; }
自动属性很棒!但现在我正在尝试做一些更复杂的事情,所以我需要编写一对自定义访问器。
private string _Name;
public string Name {
get { return _Name; }
set { _Name = value }
}
我知道当一个人使用autos时,编译器会将私有实例变量放在它的黑暗深处,但是我被宠坏了,并且不希望那个私有变量看起来毫无意义。
有没有办法在没有私有变量的情况下使用自定义访问器?
答案 0 :(得分:36)
属性根本不需要支持变量(字段)。虽然它们可用于封装简单字段,但您也可以使用它们来访问其他数据。
public Decimal GrandTotal { get { return FreightTotal + TaxTotal + LineTotal; } }
或
public string SomeStatus { get { return SomeMethodCall(); } }
如果您的目标是简单地使用属性封装某个字段,那么如果您不使用自动属性,则需要某种支持字段。
答案 1 :(得分:11)
答案是否定的,你不能这样做。 这是因为递归。 (见第9和第7行):
Line 1 : public string Name
Line 2 : {
Line 3 : get
Line 4 : {
Line 5 : return FirstName + " " + LastName;
Line 6 : }
Line 7 : set
Line 8 : {
Line 9 : Name = value; // <-- Goes back to Line 7
Line 10 : }
Line 11 : }
答案 2 :(得分:10)
例如,如果我创建这样的属性...
public int SomeValue
{
get
{
return 0;
}
}
编译器(具有您正在寻找的功能)是否会创建支持私有变量?为什么?它不需要一个。
此外,如果在编译时才创建私有值,那么您将在代码中引用什么:
public string Name {
get { return _Name; }
set { _Name = value }
}
什么是_Name
?如果您在其他地方有另一个名为_Name
的值,该怎么办?那么编译器会为此属性调用后备值?如果我需要两个支持值怎么办?编译器是否足够聪明?
public string Name
{
get
{
return string.Format("{0} {1}", _FirstName, _LastName);
}
set
{
// some parsing magic
}
}
之前有人问过,但我想在可预见的未来,答案将继续“不”。
自动属性是简单直接成员访问的语法简写。 (我认为它的推动力之一就是试图让人们直接停止创建public
值。)属性的复杂性可以超越非常容易地增加,我个人不希望编译器试图计算我可以很容易地告诉它做什么。
答案 3 :(得分:0)
我知道这是一个老问题,但这里至少还有其他选择。我正在为我自己的应用执行类似于以下内容的操作。
这可能不完全适合您的用例,但它表明可以在没有私有实例变量的情况下使用自定义 getter 和 setter。在这种情况下,getter 和 setter 是访问 Name
的 User
的 Account
属性的快捷方式或辅助方法。
我们可以通过执行 Account.AccountUser.Name = "John Doe";
来设置值,但有时这看起来有点笨拙,而且它与关注点分离的想法背道而驰。我们是否希望使用 Account
类的人知道其中嵌入了 User
?如果由于某种原因我们不这样做,即使我们将 User.Name
设为私有,我们现在仍然可以更新 AccountUser
。
在这种情况下,AccountUser
是公开的,但并非必须如此。当它是私有的时,Json 或 XML 转换实用程序(例如 Newtonsoft)应该忽略 AccountUser
并只显示 Name
,就好像 Account
是一个平面模型,而不是具有多个级别.
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Account
{
public int Id { get; set; }
public User AccountUser { get; set; }
public string Name
{
get
{
return AccountUser.Name;
}
set
{
AccountUser.Name = value;
}
}
}