1

在 C# 中为模板/抽象类的构造函数实现策略的最佳方法是什么?我有几个类都基于解析构造函数中的字符串。解析是在一个静态方法中完成的,该方法创建键值对列表并且对于所有类都是通用的,但是某些字段对于所有类也是通用的——因此我使用了一个抽象模板类。

问题是我没有看到继承抽象基类的构造函数实现的方法。否则,我将在基类中实现构造函数策略,并强制在一些抽象方法中处理列表。

编辑:为模板类添加了无效代码

public abstract class XXXMessageTemplate 
{
    public XXXMessageTemplate(string x) // implementation for the constructor 
   {
       Parse(x);//general parse function
       CommonFields();//filling common properties
       HandlePrivateProperties();//fill individual properties
       HandlePrivateStructures();//fill individual structures
    }
    abstract void HandlePrivateProperties();
    abstract void HandlePrivateStructures();
}

The actual messages should not implement any constructor and only implement the HandlePrivateProperties and HandlePrivateStructures functions.
4

4 回答 4

7

如果您希望基类构造函数的逻辑在派生类中运行,通常只需调用它:

 public Derived(...) : base(...)
 {
     // ...
 }

基类可以在构造函数期间调用抽象/虚拟方法,但通常不赞成派生类的构造函数主体尚未执行。(您需要非常强调地记录这一点。)

这回答了你的问题了吗?我不完全确定我理解这个问题 - 一些伪代码会有所帮助。

编辑:派生类必须实现构造函数。构造函数不是继承的。如果您不指定任何构造函数,编译器将提供一个无参数构造函数,该构造函数调用基本无参数构造函数。但是,您可以轻松地编写具有相同签名的构造函数,并且只需调用基类构造函数:

public Derived(string x) : base(x)
{
    // Base constructor will do all the work
}
于 2009-04-01T11:25:43.913 回答
2

为基类提供构造函数并在派生类中使用:

abstract class Base {
     // ...
     protected Base(string commonField) {
        CommonField = commonField;
     }
}

class Derived1 : Base {
     public Derived1(string commonField, string specificField) : base(commonField) {
        SpecificField = specificField;
     }
}
于 2009-04-01T11:26:05.347 回答
1

我不是 100% 确定我完全理解这个问题,但是你的意思是你希望你的子类将一个文字字符串传递给基类,就像在这个例子中一样?

public class MyMessage : XXXMessageTemplate
{
    public MyMessage() : base("MyMessage String")
    {
    }

    public override void HandlePrivateProperties()
    {
        // ...
    }

    public override void HandlePrivateStructures()
    {
        // ...
    }
}
于 2009-04-01T12:21:30.487 回答
1

正如我所看到的,问题出在 Parse(...) 方法中。不在于方法本身,而在于他的存在。您有一些原始数据(字符串 x),在用于构造对象之前必须将其转换为结构化数据(键值对)。因此,您需要以某种方式将结构化数据传递给基构造函数和子构造函数。我看到了 3 种方法:

  1. 解析基类中的数据并使用受保护的基属性将其传递给子类。
  2. 在调用构造函数之前解析数据。
  3. 解析数据代替使用。

1 您可以通过包含已解析参数的附加受保护属性来扩展 Mehrdad 答案。就像是:

abstract class Base {
     protected ParsedData ParsedData;
     // ...
     protected Base(string x) {
        ParsedData = Parse(x);
        CommonFields(); //initialize common fields using ParsedData
     }
}

class Derived1 : Base {
     public Derived1(string x) : base(x) {
        DerivedFields(); //initialize specific fields using ParsedData
     }
}

2 或者您可以将预解析的字符串传递给构造函数:

abstract class Base {
     protected ParsedData ParsedData;
     // ...
     public static ParsedData Parse(string x)
     {
        //Parse x here...
     }

     protected Base(ParsedData data) {
        CommonFields(data); //initialize common fields using data
     }
}

class Derived1 : Base {
     public Derived1(ParsedData data) : base(data) {
        DerivedFields(data); //initialize specific fields using data
     }
}

3 或解析代替用法:

abstract class Base {
     // ...
     protected Base(string x) {
        var data = Parse(x);
        CommonFields(data); //initialize common fields using data
     }
}

class Derived1 : Base {
     public Derived1(string x) : base(x) {
        var data = Parse(x);
        DerivedFields(data); //initialize specific fields using data
     }
}
于 2009-04-01T12:35:21.843 回答