我有一个抽象基类“UserFeedback”,以及两个子类“A”和“B”。
UserFeedback有一个静态的“CreateInstance()”方法。
我想 * 防止 * 调用者直接示例化一个新的UserFeedback对象:
public abstract class UserFeedback
{
public string ComponentType { get; set; }
public string UserName { get; set; }
public string EMail { get; set; }
protected UserFeedback(string componentType)
{
ComponentType = componentType;
}
public static UserFeedback CreateInstance(string componentType)
{
switch (componentType)
{
case "A":
return new A(componentType); // Line 32
case "B":
return new B(componentType); // Line 34
default:
throw new ArgumentException(String.Format("User Feedback Type: {0}", componentType));
}
}
public abstract string GetTitle(string operation);
}
public class A : UserFeedback
{
protected A(string componentType) : base(componentType)
{ }
public override string GetTitle(string operation)
{
return "A Feedback";
}
}
public class B : UserFeedback
{
protected B(string componentType) : base(componentType)
{ }
public override string GetTitle(string operation)
{
return "B Feedback";
}
}
这在第32和34行给出了编译错误:
Error CS0122 'A.A(string)' is inaccessible due to its protection level
在C#/.NET的新版本中,有没有“简单”的方法来实现这一点?
或者我应该放弃,让A()和B()的构造函数“公共”?
4条答案
按热度按时间iyr7buue1#
您可以简单地将A和B设置为私有Nested Types
ekqde3dh2#
如果您真的不希望客户端创建派生类的示例,而只希望它们通过静态
CreateInstance
方法,一种可能的方法是将派生类设置为private
,并将它们与Userfeedback
放在同一个类中。如果您确实采用这种方法,则无法强制转换到这些示例,因为它们不可见gwo2fgha3#
在您的代码中,子类
A
可以接收任何值,即使只有A
是有效的。为什么在子类中甚至需要构造函数参数?如果不需要它,为什么不把它公开,让调用者示例化它呢?如果上面的情况成立,让调用者直接示例化
A
和B
实现。这些对象具有示例化自身所需的信息,不应该需要构造函数参数来告诉它们。首先,让我们从抽象类中删除静态
CreateInstance
方法。接下来,在子类中,将构造函数设为公共无参数构造函数,因为我们不需要外部任何东西来告诉我们
A
或B
是什么。它们已经知道它们是什么,所以我们可以将其硬编码到基构造函数调用中。这还有一个额外的好处,即在实现新的子类时不必更新基本
UserFeedback
类。我在我的例子中使用了
nameof()
来去掉字符串。1l5u6lss4#
有一个不同的选择。有时候,当出现这种情况时,嵌套类是不可取的,或者难以实现。
当它发生时,
protected internal
构造函数是你的朋友。只有您自己的程序集可以调用基构造函数,因此只有您的程序集可以示例化它。我习惯于看到
CreateInstance()
做一些很好的事情,比如访问基于#if
的几个实现中的一个或其他奇特的东西。还有一种我不完全理解的机制,通过这种机制,一个特定的程序集可以在请求时加载,它可以访问protected external
构造函数,并且这个程序集在编译时是由你的程序集祝福的,所以没有其他人可以做它。