2010-03-10 72 views
1

要使类实例正常工作,应该正确初始化一些字段,初始化这些字段的策略是什么,应该通过构造函数给出什么,应该通过属性给出什么?c中的实例初始化策略#

我的困惑是,如果构造函数需要一个长参数列表,很难使用,如果通过属性,我倾向于忘记设置一些属性。

最佳做法是什么?

+0

有时,当你发现构造函数列表很长时,类(类型)做得太多了。当然,有时它是不可避免的... – 2010-03-10 04:57:55

回答

2

你必须问自己,如果你的课程需要创造许多东西,也许它做得太多。这是一个迹象,你应该重新考虑你的设计,或者说构造函数在做什么“工作”。

确实,你不应该能够创建一个无效状态的实例;因此构造函数应该把你需要的所有属性设为一个有效的状态。

在某种程度上,它取决于你的模型。例如,我使用的ORM具有构造函数带一个参数;它可以加载所有其他属性的ID。如果我必须全部通过它们(这真的是ORM的工作;设置这个对象),这会很麻烦。所以从这个意义上说,你可以说你有一个“无效”对象(没有属性设置)。但你会错的;你实际上有一个“空白”或“空”的对象。这不同于无效。

因此,仔细想想它是什么意思是你的对象是“无效的”。如果其他方法使用这个对象,我会认为它是无效的,并且因为没有设置某个东西而抛出异常。使用这个逻辑来确定构造函数中需要什么,以及稍后可以设置什么(通过其他进程)。

2

这总是一种平衡行为 - 您不希望具有需要许多参数的构造函数,但也不希望用户在对象处于有效状态之前设置许多属性。不幸的是,这里没有真正的指导,因为您必须对当前的情况做出最佳判断。

很多时候,您可能需要创建一个具有许多属性和许多可能配置的复合类型(例如System.Web.Page)。复合类型往往具有简单的构造函数,只需很少的参数或不需要参数,而且所有的值都必须通过属性来设置复合类型是由较低级别分解(或简单)类型组成的高级类型。

外部类型往往更简单,包含更少的状态,并且可以通过它们的构造函数完全初始化。因子类型的例子是System.StringSystem.Int32。这些类型非常简单,并且往往是复合类型的构建块。

如果您的类型是因式分类,那么尽量让消费者通过构造函数完全初始化类型。如果你的类型是一个复合类型,那么最好提供一些参数很少或没有的简单构造函数,并要求消费者通过属性设置器来配置实例。

+1

+1。我将指出,在“复合类型”的情况下,您需要定义一个定义良好的合同,确定必须设置哪些属性才能为实例指定其状态。记下它的地狱。这样,一年下来,该对象不会受到可怕的配置:) – Kivin 2010-03-10 05:18:31

+0

@Kivin - 绝对! – 2010-03-10 05:19:21

1

现在,.NET 3.5允许您在创建时设置任何属性,我通常将任何具有参数的构造函数限制在实例绝对必须具有创建值的情况下。实际上没有任何其他理由使用参数IMO添加构造函数重载。

1

我认为最好的办法是进行验证,一般尽量保持构造不带参数,因为它往往是不同的.NET库的要求。

通过验证,您将不得不检查对象的有效性,但这是很常见的事情。线之间的东西:

public interface IValidateable { 
    IEnumerable<string> Validate(); 
} 

public class Person : IValidateable { 
    public string Title { get; set; } 
    public string First { get; set; } 
    public string Last { get; set; } 
    public Address HomeAddress { get; set; } 

    public Person() { 
     HomeAddress = new Address(); 
    } 


    public IEnumerable<string> Validate() { 
     var errors = new List<string>(); 
     if (string.IsNullOrEmpty(First)) 
     errors.Add("First name is required."); 
     // And so on... 
     return errors; 
    }  
} 

// Usage 
var p1 = new Person(); 
var p2 = new Person { 
    First = "Dmitriy" 
    }; 

if (p1.Validate().Any()) { 
    // Do something with invalid object 
} 
+0

如果班级不是商务班,可能我应该去检查和提出例外。 – Benny 2010-03-10 05:04:41

+0

是的,这是另一种选择。 – 2010-03-10 05:18:16