好吧,我的问题很明显。我有一个类,我想确保这个类只有一个公共构造函数。此外,我还想确保构造函数只有1个参数。我的类将被许多不同的开发人员修改,我正在寻找一种方法来确保他们不会编写比当前指定的更多的构造函数。可能吗?如果是,那怎么办?
注意,我的类继承自另一个类,该类当前没有任何构造函数,但将来可能会有。我不知道这些信息是否会影响答案,只是考虑添加它。
请帮忙! 提前谢谢!
答案 0 :(得分:4)
您可以考虑编写单元测试来编码此设计约束。只要测试没有进行,就会在约束被打破时发出警告。
这对于你的班级中详细说明这种约束的好评论来说是一个很好的例子。
可以扩展以下测试方法以提供可以测试派生类型而不是单个类型的测试。此方法是一种静态分析,并消除了通过反射进行昂贵的运行时检查所产生的开销。测试可确保在构建时验证设计约束,而不是在运行时验证代码发布后验证。
[Test]
public void myClass_must_have_one_single_paramter_ctor()
{
Type type = typeof(MyClass);
const BindingFlags Flags = (BindingFlags.Public | BindingFlags.Instance);
ConstructorInfo[] ctors = type.GetConstructors(Flags);
Assert.AreEqual(1, ctors.Length, "Ctor count.");
ParameterInfo[] args = ctors[0].GetParameters();
Assert.AreEqual(1, args.Length, "Ctor parameter count.");
Assert.AreEqual(typeof(string), args[0].ParameterType, "Ctor parameter type.");
}
public class MyClass
{
public MyClass(string woo) {}
}
答案 1 :(得分:3)
所有类都有一个构造函数。如果您未在源代码中指定一个,则编译器将添加一个空的公共构造函数 - 相当于:
public class MyClass
{
public MyClass()
{
}
}
但是,如果在源中指定至少一个构造函数,则只会创建您明确指定的构造函数,例如:以下类有一个公共构造函数,它接受一个字符串参数:
public class MyClass
{
public MyClass(string myParameter)
{
...
}
}
简而言之,您无需做任何特别的事情。如果你只需要一个公共构造函数,那么......只需编写一个公共构造函数。
答案 2 :(得分:2)
只有编写类的人才能限制构造函数的数量和类型。 所以,如果是你,那么你可以按照你想要的方式编写代码。
答案 3 :(得分:1)
Constructors are not inherited。
你的类只有 你编写的构造函数,除了(作为others have pointed out)一个默认的公共构造函数,当你没有明确地提供你的一个时,由编译器生成自己的。
答案 4 :(得分:1)
这可以通过反射来实现。您唯一需要注意的是,开发人员不应该访问或编辑基类代码。
class Program
{
static void Main(string[] args)
{
Inherited obj = new Inherited("Alpha");
obj.test();
Inherited1 obj1 = new Inherited1(); //This will fail as there is no ctor with single param.
obj1.test();
}
}
public class MyBase
{
private static IList<string> ValidatedClasses = new List<string>();
public MyBase()
{
if(!ValidatedClasses.Contains(this.GetType().FullName) &&
!ValidateConstructorLogic())
{
throw new ApplicationException("Expected consturctor with single argument");
}
}
public bool ValidateConstructorLogic()
{
bool ValidConstFound = false;
foreach (var info in this.GetType().GetConstructors())
{
if(info.GetParameters().Length ==1)
{
lock (ValidatedClasses)
{
ValidatedClasses.Add(this.GetType().FullName);
}
ValidConstFound = true;
}
}
return ValidConstFound;
}
}
public class Inherited:MyBase
{
public Inherited(string test)
{
Console.WriteLine("Ctor");
}
public void test()
{
Console.WriteLine("TEST called");
}
}
public class Inherited1 : MyBase
{
public void test()
{
Console.WriteLine("TEST called");
}
}
您可以使用FxCop根据一组预定义规则验证您的代码。我相信这可能是你问题的恰当解决方案。如果您在创建自定义FxCop规则方面需要帮助,请参阅此article。
答案 5 :(得分:0)
您可以尝试使用nested builder,如Jon Skeet所述。基本上:您强制用户浏览构建器,然后调用私有类构造函数。由于类构造函数是私有的,因此只有嵌套构建器才能访问它。
替代方法:使用静态工厂方法,使构造函数为私有&amp;记录你的意图。
答案 6 :(得分:0)
根据您的评论,我不认为这是一个“编码”问题。这是一项政策和执法问题。您不希望团队中的其他开发人员创建更多构造函数。
在这种情况下,请告诉他们。负责源代码存储库的任何人都可以通过拒绝违反策略的更改来强制执行它。添加代码来处理这个问题只会毫无理由地向用户添加运行时惩罚。