1

我有一个具有 2 个属性和一个构造函数的类:

public class Card
{
    public int CardName {get;set;}
    public bool IsActive {get;set;}

    public Card (int cardName, bool isActive)
    {
        CardName = cardName;
        IsActive = isActive;
    }
}

如何强制开发人员使用构造函数而不是执行以下操作:

var card = new Card{ CardName = "blab", IsActive = true };

顺便说一句,上面的语句叫什么?这是一个延迟加载语句吗?

4

3 回答 3

4

你已经有了。

由于没有空的构造函数,您已经删除了使用对象初始化方法创建对象的能力。

这个:

var card = new Card{ CardName = "blab", IsActive = true };

和这个一样

var card = new Card() { CardName = "blab", IsActive = true };

在这种情况下new Card()是无效的。

于 2012-07-16T15:46:47.210 回答
1

这取决于您为什么要阻止有问题的语法。

对象初始值设定项语法是在构造后立即设置一堆属性的简写。也就是说,这个:

var c = new Card { CardName = "foo", IsActive = true };

在语义上与此相同:

var c = new Card();
c.CardName = "foo";
c.IsActive = true;

在这两种情况下,构造函数都会运行,但紧随其后的是一系列属性初始化程序以应用于新对象。

在您的情况下,由于没有无参数构造函数,因此您不能按照您发布的方式使用对象初始值设定项语法。但是,将构造函数参数与对象初始化器一起传递是合法的,因此以下内容对于您类是合法的:

var c = new Card("", false) { CardName = "foo", IsActive = true };

(有人可能会争辩说,这种语法比简单地将值传递给构造函数更清楚地说明了值的含义;有人也可能会争辩说它过于固执:)我可以选择任何一种方式)

您可以通过删除这些属性的公共设置器来阻止第二种语法工作。例如,如果您的目标是防止用户更改传递给构造函数的值Card,例如创建一个不可变对象,那将是可行的方法。

不过,我应该指出,如果我的一个晚辈在工作中问我这个问题,我真的很想知道为什么他们发现有必要阻止使用对象初始化。当然,有正当的理由,但它们通常不是问题的根源。对象初始化器是一件好事——在某些情况下这种语法非常方便(尤其是使用 LINQ)并且我一直都在使用它。

如果您根据初始值在构造函数中进行某种设置,但这些属性是可公开设置的,那么您已经不得不处理用户在构造后更改这些值的情况。如果您的目标只是确保在第一次构造对象时发生一些“设置”代码,则将该代码放入默认构造函数并将它们链接在一起:

public class Card
{
  public string CardName { get; set; }
  public bool IsActive { get; set; }

  public Card() 
  { 
    // setup code here. 
  }

  public Card ( string name, bool active ) 
    : this()
  {
    this.CardName = name;
    this.IsActive = active;
  }
}
于 2012-07-16T16:03:00.007 回答
0

将属性的 getter 声明为“Private”。类似的东西Public int CardName {private get; set;}

于 2012-07-16T15:46:53.573 回答