吸气剂,制定者和属性最佳实践.Java与C#

Viv*_*ath 90 c# java properties getter-setter

我现在正在上C#课程,我正在努力寻找最好的做事方式.我来自Java背景,因此我只熟悉Java最佳实践; 我是C#新手!

在Java中,如果我有私有财产,我会这样做;

private String name;

public void setName(String name) {
   this.name = name;
}

public String getName() {
   return this.name;
}
Run Code Online (Sandbox Code Playgroud)

在C#中,我看到有很多方法可以做到这一点.

我可以像Java一样做:

private string name;

public void setName(string name) {
   this.name = name;
}

public string getName() {
   return this.name;
}
Run Code Online (Sandbox Code Playgroud)

或者我可以这样做:

private string name;

public string Name {
   get { return name; }
   set { name = value; }
}
Run Code Online (Sandbox Code Playgroud)

要么:

public string Name { get; set; }
Run Code Online (Sandbox Code Playgroud)

我应该使用哪一个,每种方法涉及哪些警告或细微之处?在创建类时,我遵循我从Java中了解的一般最佳实践(特别是阅读Effective Java).因此,例如,我赞成不变性(仅在必要时提供setter).我很想知道这些实践如何适应C#中提供setter和getter的各种方法; 基本上,我如何将Java世界的最佳实践转换为C#?

编辑

我发布这篇文章是对Jon Skeet答案的评论,但后来很久了:

那么一个非平凡的财产(也许,可能有重要的处理和验证)?我是否仍然可以通过公共属性公开它,但是逻辑封装在getset?为什么我应该/我应该使用专用的setter和getter方法(具有相关的处理和验证逻辑).

Jon*_*eet 86

前C#6

我会使用最后一个,这是一个微不足道的财产.请注意,我将此称为公共属性,因为getter和setter都是公共的.

自动实现属性的不变性有点痛苦 - 你不能写一个只有getter的auto-property; 你最接近的是:

public string Foo { get; private set; }
Run Code Online (Sandbox Code Playgroud)

这不是真正不可改变的......只是在课堂外不可变的.因此,您可能希望使用真正的只读属性:

private readonly string foo;
public string Foo { get { return foo; } }
Run Code Online (Sandbox Code Playgroud)

你绝对不想写getName()setName().在某些情况下,编写Get/Set方法而不是使用属性是有意义的,特别是如果它们可能很昂贵并且您希望强调这一点.但是,您希望遵循PascalCase的.NET命名约定来获取方法,并且您不希望这样的普通属性无论如何都要用普通方法实现 - 这里的属性更加惯用.

C#6

万岁,我们终于有了适当的只读自动实现的属性:

// This can only be assigned to within the constructor
public string Foo { get; }
Run Code Online (Sandbox Code Playgroud)

同样,对于只读属性,其需要做一些工作,就可以使用会员浓郁的属性:

public double Area => height * width;
Run Code Online (Sandbox Code Playgroud)

  • 更确切地说:任何代码reiew都会指出java方式是一种绕过有效语言和(!)运行时构造的hack,并将属性的使用视为proeprty(即object.property ="value").在一些团队中,这将导致一种关于态度的好谈 - 取决于资历以及将这种态度用于竞争对手的动机.说真的,不要打败语言.特别是因为java"方式"是为了不修改实际属性支持的语言而选择的hack. (5认同)
  • 要回答你的编辑:你可以使用get/set方法,使用你想要的任何数量的逻辑.我们经常这样做,尤其是验证.但是,最佳做法是不要在属性中使用很多慢速逻辑(例如数据库访问),危险逻辑(异常抛出)或突变(更改大量状态).预计财产或多或少会像一个简单的国家.应该使用函数来指示更多内容. (4认同)
  • @rtindru:是的,我知道这一点.写一个只读属性是完全可能的.但是如果没有set访问器,则无法声明*自动实现的*属性. (2认同)
  • 从C#6开始[你现在可以拥有没有set accessor的自动属性](https://github.com/dotnet/roslyn/wiki/Languages-features-in-C%23-6-and-VB-14), (`public int Y {get;} = y;`). (2认同)

jer*_*lan 17

如果你需要的只是一个存储一些数据的变量:

public string Name { get; set; }
Run Code Online (Sandbox Code Playgroud)

想让它看起来只读吗?

public string Name { get; private set; }
Run Code Online (Sandbox Code Playgroud)

甚至更好......

private readonly string _name;

...

public string Name { get { return _name; } }
Run Code Online (Sandbox Code Playgroud)

想要在分配财产之前做一些价值检查吗?

public string Name 
{
   get { return m_name; }
   set
   {
      if (value == null)
         throw new ArgumentNullException("value");

      m_name = value;
   }
}
Run Code Online (Sandbox Code Playgroud)

一般来说,GetXyz()和SetXyz()仅在某些情况下使用,你只需要在感觉正确时使用你的肠道.一般来说,我会说我希望大多数get/set属性不包含很多逻辑,并且几乎没有任何意外的副作用.如果读取属性值需要调用服务或从用户那里获取输入以构建我正在请求的对象,那么我会将其包装到一个方法中,并将其称为类似于BuildXyz()而不是GetXyz().

  • 私人的setter!=不可变的 (3认同)
  • 我不会在属性中抛出异常,我宁愿使用带有契约的方法设置器来指定这种特定的行为.如果属性是int类型,我希望每个int都符合条件.在我看来,调用异常抛出的东西不是_simple_,根据我的说法,INotifyPropertyChanged类型调用更多的是在那一行. (2认同)

Ed *_* S. 12

使用C#中的属性,而不是get/set方法.它们是为了您的方便,它是惯用的.

至于你的两个C#例子,一个是另一个的语法糖.如果您需要的只是一个实例变量的简单包装器,请使用auto属性,当您需要在getter和/或setter中添加逻辑时,请使用完整版本.


Jam*_*are 5

在C#favor属性中,用于为get和/或set公开私有字段.你提到的形式是一个autoproperty,其中get和set会自动为你生成一个隐藏的枢轴支持字段.

我尽可能喜欢自动属性,但你永远不应该在C#中使用set/get方法对.


Ste*_*ris 5

public string Name { get; set; }
Run Code Online (Sandbox Code Playgroud)

这只是一个自动实现的属性,在技术上与普通属性相同.编译时将创建一个支持字段.

所有属性最终都转换为函数,因此最终的实际编译实现与您在Java中习惯的相同.

当您不必对支持字段执行特定操作时,请使用自动实现的属性.否则使用普通财产.当操作有副作用或计算成本高时使用get和set函数,否则使用属性.


Waq*_*aja 5

首先让我试着解释你写的内容:

// private member -- not a property
private string name;

/// public method -- not a property
public void setName(string name) {
   this.name = name;
}

/// public method -- not a property
public string getName() {
   return this.name;
}

// yes it is property structure before .Net 3.0
private string name;
public string Name {
   get { return name; }
   set { name = value; }
}
Run Code Online (Sandbox Code Playgroud)

现在也使用这种结构,但如果你想要做一些额外的功能,它是最合适的,例如当设置一个值时,你可以解析它以将其大写并将其保存在私有成员中以供内部使用.

使用.net framework 3.0

// this style is introduced, which is more common, and suppose to be best
public string Name { get; set; }

//You can more customize it
public string Name
{
    get;
    private set;    // means value could be set internally, and accessed through out
}
Run Code Online (Sandbox Code Playgroud)

祝你在C#中好运