2011-07-28 74 views
5

我是新来的C#语法。我写了下面的类(代码隐藏我的网站的母版):获取并设置在C#

public partial class MasterPagePro : System.Web.UI.MasterPage 
{ 
    public String pageTitle 
    { 
     get 
     { 
      if (this.pageTitle == null) 
       return ""; 
      else 
       return " - " + this.pageTitle; 
     } 
    } 

} 

然而,当我尝试访问PAGETITLE这样的HTML:

<title>MySite<%=pageTitle%></title> 

我得到一个计算器错误。看看代码,很明显,问题在于该方法递归调用自身,但我不知道要编写什么来解决此问题。我可以做这样的事情:

public partial class MasterPagePro : System.Web.UI.MasterPage 
{ 
    private String _pageTitle 

    public String pageTitle 
    { 
     get 
     { 
      if (_pageTitle == null) 
       return ""; 
      else 
       return " - " + _pageTitle; 
     } 
     set { _pageTitle = value; } 
    } 
} 

但是,这似乎打败了语法快捷方式的所有点。什么是正确的方法来做到这一点?

回答

6

在第一个示例中,您期望编译器知道您是否实际上要递归调用相同的属性。由于编译器无法知道你的意图,所以它会按照书面的方式创建代码,正如你所指出的那样,这会导致一个堆栈溢出。

当你有一个简单的赋值/返回setter/getter属性时,syntatic捷径是。编译器为您创建支持类成员,并生成get/set例程。

例如:

class foo { 

public int myInt; 

public int MyInt { get { return myInt;} 
        set { myInt = value;} } 

} 

VS

class foo { 

public int MyInt { get; set; } 

} 

在这种情况下,它是不是在暧昧所有你正在尝试做的,因此编译器可以帮帮忙,自动生成有必要的。

如果您需要实现自定义setter/getter功能,也包括设置值,则必须使用备份类成员,如第二个示例中所示。

3

您提供的第二个代码块与我意识到的在c#中实现非平凡(具有逻辑)属性的“正确”方式非常接近。

1
  • 列表项

你是返还财产,这将再次走进 get。这个属性是否有一个后台?

您提出的方法是正确的。属性的概念只是语法糖而不是获取和设置方法,而不是消除对本地域的需求。自动属性就是语法糖,但在这种情况下你不能提供实现。

什么,你可能会想的是自动特性:

public string MyName { get; set; } 

但对于这些,你无法实现获取或设置。

另外,如果您正在为一个属性一个不平凡的实施,请注意,有几个原则:

  • get和set动作要轻巧,即快。
  • 属性的返回值在调用之间不应该改变,除非它被设置为一个不同的值(例如,如果类的内部状态导致不同的值,建议使用方法来返回值)。
+0

呃,我明白了。我认为这样做是隐含地创造了沿线的某个支持领域。 – Oliver

+0

@Oliver后台字段仅在自动属性的情况下隐式创建。 –

+0

你不一定希望它在后台自动生成一个字段。例如,从接口继承时:'bool SupportsSomeProperty {get {return true; }}' – climbage

6

当您以这种方式使用吸气器时,您还需要手动添加一个字段,就像您在第二个示例中那样。

您不能只引用与第一个示例中相同的属性。

你提到了一个语法快捷方式,但是根据我所知,你并没有使用快捷方式。

对性能的快捷方式时,没有处理的变量它返回的将是之前完成:

public string pageTitle{get;set;} 

这自动为您创建支持字段。

1

“语法快捷方式”不一定是句法快捷方式。如果你想使用自动属性,你可以使用

public String PageTitle {get;组; }

和一切都在你身边,包括支持领域。属性的真正意义在于隐藏实现者的后台... OOP,抽象和继承以及所有这些东西。使用属性,您可以添加验证或更改返回格式,而无需搜索对后台字段的每个访问实例。

1

此外,属性(get和set语法)通常具有PascalCase,即PageTitle。

+0

谢谢。我来自Java背景,它使用不同的约定。我的命名方案目前非常混乱。 – Oliver

+0

这是可以理解的。我也来自java。 C#约定有时可能很奇怪。上周我写了一些如下内容:Fixation.Fixation Fixation = new Fixation()也许不是名字的最佳选择,但是从课外更有意义,所以我坚持了。 –