2014-11-21 64 views
1

我的类有十个属性,必须先使用该类才能使用该类。如何强制客户端设置某些属性

我想在调用任何类的方法之前强制(或者至少非常强烈地鼓励,最好带有警告)我的类的用户设置这些属性。

我可以使用一个构造函数,它将所有属性的值作为参数,但我不想因为那么多参数太笨重。

我可以检查类的所有方法中的属性值,但这太迟了 - 我想要一个编译时检查。

我该怎么办?

+9

这恰恰是什么构造函数。他们让对象进入一种可用的状态 - 你不能保证客户端会或不会调用方法或设置属性等。如果有很多属性需要设置,也许这​​个类会尝试做太多的事情,本身应该分成几个小类 – 2014-11-21 15:17:45

+0

你可以将你的属性移动到他们自己的类“PropClass”中。然后让你的类有一个属性'PropClass',并在构造函数中使用'PropClass'参数。 – Jonesopolis 2014-11-21 15:17:56

+0

任何其他建议比使用构造函数将使用最丑的解决方案。你能向我们展示你的班级图表吗?太多的参数暗示你的班级做得太多。 – SBI 2014-11-21 15:18:13

回答

5

也许你可以使用流利接口的Builder Pattern的一些变化。你可能有某种步骤或者某些你不能跳过某些属性的东西。例如,要设置的助洗剂的特性y您需要,设置属性X.

new Builder().SetX(10).SetY(20) //compiles because SetX returns a class with SetY method 
new Builder().SetY(20) //does not compile because the builder only has SetX method 

为了避免具有多个类由该方法返回的对象可能需要具有多个接口的一个类的每一个公开只有一个方法。

在另一方面,我可能会去的构造,即使有很多的参数

+1

是的,Builder模式很适合这类问题。例如。你有一个内部构造函数的复杂对象。然后你设计其他对象来构建你的对象。例如。称为NetPipeFactory的类可能包含创建NetPipe对象(具有复杂配置)的必要方法。或者,也许你有一个名为Graphics的类,它使用FromImage,FromHnd等等等方法创建自己。 – 2014-11-21 15:38:27

0

一些想法:


可选参数应该减少构造的烂摊子参数

public class SomeClass 
{ 
    public int Property1 {get; private set;} 
    public int Property2 {get; private set;} 
    public int Property3 {get; private set;} 

    public SomeClass(int some1 = 1, int some2 = 2, int some3 = 3) 
    { 
     SomeProperty1 = some1; 
     SomeProperty2 = some2; 
     SomeProperty3 = some3; 
    } 
} 

易于使用:

var a = new SomeClass(some3: 123); 

您可以尝试使用nullables到throw,如果某个值未设置

public class SomeClass 
{ 
    private int? _property1; 
    public int Property1 { get { return (int)_property1.Value; } } // will throw 

    public SomeClass() {} 

    public int SomeMethod() 
    { 
     int val = _property1.Value; // will throw 
     ... 
     return 123; 
    } 
} 
0

问题具有复杂的构造,是他们往往不解释意源。例如,假设您有一个可以从字节数组,图像,句柄,内存地址,base64编码的字符串或更多等创建的类。

要为每个人创建构造函数,您不能真正描绘那个。例如。如果一个构造函数接受一个字符串(即使它的参数名是base64String),它也不是很直观。

一个更好的办法我遵循复杂的构造是让我的私人的构造,而是我通过返回它的实例化自我的public static方法暴露我对象的创建。例如,可以使用.Net图形类。你可以从图像或窗口句柄等创建图形类,并为每个它有方法“FromImage,FromHandle等”。遵循这种模式,在我看来,更直观,因为您知道您只是在方法名称中从图像创建它,这可以是一个体面的方式来驯服复杂的构造函数和初始化模式。

0

As @Stilgar指出Builder模式是一个很好的答案。根据您希望给予最终用户的“鼓励”级别,您可以使用具有默认参数的构造函数。这样他们将看到他们应该设置的东西(用Intellisense),但也可以选择他们希望用命名参数设置的东西。

 public ComplexObject(string P1 = "Test", int P2 = 123, double P3 = 3.1415927) 
     { 

     } 

enter image description here