我想从基础构造函数中调用子类构造函数,并将创建的子类对象作为基类对象。 代码看起来像这样。
class Text
{
public string OriginalText;
public Text() { }
public Text(string text)
{
OriginalText = text;
text = FormatText(text); // like text.ToUpper().Trim()
if (Category1.Check(text))
new Category1(text);
else if (Category2.Check(text))
new Category2(text);
else if (Category3.Check(text))
new Category3(text);
}
}
class Category1 : Text
{
public string Property1;
public Category1(string text)
{
Property1 = text + "#1";
}
static public bool Check(string text)
{
return text == "category1";
}
}
class Category2 : Text
{
public string Property2;
public Category2(string text)
{
Property2 = text + "(2)";
}
static public bool Check(string text)
{
return text == "category2";
}
}
class Category3 : Text
{
public string Property3;
public Category3(string text)
{
Property3 = text + "%3";
}
static public bool Check(string text)
{
return text == "category3";
}
}
但是,var t = new Text("category1")
不是子类的对象。我通过评估t is Category1
false
来检查了这一点。我尝试添加
在return
前面new Category1(text)
,但由于构造函数返回void类型,因此此方法失败。以下是从日语翻译的错误消息。
An object statement can't be used after the keyword return since MainWindow.Text.Text(string)' returns void type
解决此问题的一种方法是定义一个返回子类对象的静态方法。
static public Text GetCategory(string text)
{
text = FormatText(text);
if (Category1.Check(text))
return new Category1(text);
else if (Category2.Check(text))
return new Category2(text);
else if (Category3.Check(text))
return new Category3(text);
return null;
}
但是,这次,OriginalText = text;
无法使用,因为这是一种静态方法。我承认可以通过向每个
if
陈述的单一内容
string tmp1 = text;
text = FormatText(text);
var c1 = new Category1(text);
c1.OriginalText = tmp1;
return c1;
或在每个子类构造函数中设置OriginalText
。
但这会使代码冗长,冗余,难以阅读和维护。我想在同一个地方聚合常见的进程,我的意思是基础构造函数。
谷歌搜索"调用子类构造函数c#"给了我两篇文章,对我来说没有答案。
Calling subclass constructor from static base class method
这是无关紧要的。它是关于调用从基类继承的静态子类方法。
How to call subclass constructor only in inheritence
这是不同的。这个是关于调用子类构造函数而不调用基类构造函数。
我该如何处理这个问题?
答案 0 :(得分:2)
在您正在讨论的代码块中,您正在创建一个新实例,但它永远不会分配给变量,也不能从构造函数返回:
if (Category1.Check(text))
new Category1(text); // <-- wrong!
构造函数是一种在给定类型的内存中初始化新创建的空间的方法。你不能从构造函数中改变类型!
你想要一个工厂模式,就像你在第二个例子中给出的那样。这是您最好也是唯一的选择:
static public Text GetCategory(string text)
{
text = FormatText(text);
if (Category1.Check(text))
return new Category1(text);
答案 1 :(得分:0)
正如Patrick正确解释的那样,您想要使用工厂模式。
关于OriginalText
,您不必重复此代码。只需创建这样的工厂方法:
static public Text GetCategory(string text)
{
var formattedText = FormatText(text);
Text result = null;
if (Category1.Check(formattedText))
result = new Category1(formattedText);
else if (Category2.Check(formattedText))
result = new Category2(formattedText);
else if (Category3.Check(formattedText))
result = new Category3(formattedText);
if(result != null)
result.OriginalText = text;
return result;
}