为什么在实体中需要私有的 setter 方法?

10

我还在逐渐熟悉Entity Framework,但我见过以下类似代码,其中实体的id具有私有设置器。

public int Id { get; private set; }
public string FirstName { get; set; }
public string LastName { get; set; }

为什么一些属性需要私有的setter方法?比如说这个Id字段在数据库中是自动生成的,所以它被设置为私有的?

此外,为什么我们需要在实体类中同时拥有私有构造函数和公共构造函数?

private Emp() { }

public Emp(string name, string lastname)
{
    FirstName = firstname;
    LastName = lastname;       
}
3个回答

16
您无需自己设置主键列的值,因为它是由数据库自动生成的,那么为什么要允许做毫无意义的事情呢?因此,您将Id的setter设置为private。即使它是私有的,EF在实例化对象时仍然可以设置这个属性。
构造函数也是同样的道理。EF要求实体必须有一个无参数构造函数,但它可以是私有的。但是,在您的示例中,您不希望用户在没有提供名字的情况下创建实体,因为很可能这些名字是必需的,并且您想要不可避免地表达这种意图。因此,您有一个构造函数用于创建实体(同时设置两个名字),还有一个用于EF从数据库接收到的对象实例化(无参数构造函数)。
请注意,EF不需要私有setter和构造函数的这种配置。所有这些都是为了方便开发人员,以防止不希望的行为(设置Id字段或在不提供名称的情况下创建Emp实体)。

3
@Happy,EF需要有“无参数构造函数”才能创建实体对象。它可以是私有的或公共的,这并不重要。所有其他构造函数都是可选的。通常人们只创建一个公共的“无参数构造函数”(或不创建任何构造函数-然后“无参数构造函数”会自动生成)。但在您的示例中,作者希望“防止”创建没有提供名字和姓氏的新员工(以便开发人员不会忘记这样做),所以有两个构造函数,其中一个是私有的。 - Evk
不,这不是强制性的。同时,拥有私有setter也不是必须的。你可以完全省略构造函数(公共无参构造函数将自动生成),并使用公共setter。你示例中的所有内容都是为了方便起见,以便您(开发人员)无法意外地执行对模型没有意义的操作。 - Evk

5

私有setter对于为用户提供只读属性非常有用,这意味着您无法修改该属性。因为某些属性(如ID)您不希望其被修改,或者如果您想要添加一些验证或在类级别上设置该属性(从类内部)。在这种情况下,我们使用私有setter。

public int Id { get; private set; }

或者有时候像这样
private int Id ;
public int Id 
{
    get { return Id ; }
}

3
除了提供的答案外,随着C# 6.0的引入,您不再需要使用private setters来设置属性的值。
您可以使用以下代码代替private setters:
public class Appointment
{
  public DateTime TimeStamp { get; } = DateTime.UtcNow;
  public string User { get; } =
    System.Security.Principal.WindowsPrincipal.Current.Identity.Name;
  public string Subject{ get; } = "New Subject"
}

你可以在这里查看更多信息。
至于私有构造函数:当你不希望类被类外代码创建时,可以使用私有构造函数。 单例模式, 工厂模式, 静态方法对象 是限制构造函数很有用的例子。

构造函数呢? - James
这将仅设置getter属性的初始值,从而使其表现为常量。 - Verbe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接