首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何重写方法保存模板方法模式

如何重写方法保存模板方法模式
EN

Stack Overflow用户
提问于 2019-01-02 21:19:48
回答 3查看 67关注 0票数 0

我确实有一个抽象类,在构造函数上,我调用在同一个类上声明的抽象方法,我之所以这样做,是因为我确实想强制所有派生类不仅实现我的抽象方法,而且还调用它(我认为这就是模板方法模式的用武之地)。

顺便说一句:我知道这不是确保所有东西都被正确写入的最好方法,但由于外部问题,我想尽量减少我未来的问题与糟糕的实现。代码片段如下:

代码语言:javascript
复制
public abstract class Generic
{
    public Generic()
    {
        Console.WriteLine("This is the generic");

        this.SetRules();
    }

    protected abstract void SetRules();
}

嗯,在我的一个派生类上,需要在声明上设置一个私有变量,我想在重写方法中使用这个变量。因为我不知道每个派生类需要多少可能性,所以我想根据需要在每个派生类中声明它。下面是一个示例:

代码语言:javascript
复制
public class Derivated2 : Generic
{
    private int _parameter;

    public Derivated2(int parameter)
    {
        this._parameter = parameter;
    }

    protected override void SetRules()
    {
        int x = 0;
        x = 1 + 3;

        Console.WriteLine(String.Concat("This is the derivated2 with x: ", x, "; _parameter: ", _parameter));
    }
}

现在来看看问题所在;

当我调用我的derivated2类时,我不能使用/查看在声明中指定的变量值:

代码语言:javascript
复制
public static void Main()
{
    Derivated2 _class1 = new Derivated2(2);
}

我的输出是:

代码语言:javascript
复制
This is the generic
This is the derivated2 one with x: 4; _parameter: 0

如何在重写的asbtract方法中查看/使用我的变量?如果我不能,那么实现我的目标的最佳方法是什么?无论开发人员做什么,都将调用SetRules方法,并且还可以在其派生类中使用私有变量。

下面是我完成的完整代码:

Calling SetRules on Abstract Generic Class

Calling SetRules on Derivated Class

EN

回答 3

Stack Overflow用户

发布于 2019-01-02 21:34:33

问题是您调用的是泛型构造函数,它将在调用Derivated2构造函数之前调用SetRules,这意味着您的参数尚未设置。你可以试试这个。

代码语言:javascript
复制
public abstract class Generic
{
    public Generic(int parameter)
    {
        Console.WriteLine("This is the generic");

        this.SetRules(parameter);
    }

    protected abstract void SetRules(int paramter);
}

public class Derivated2 : Generic
{

    public Derivated2(int parameter) : base(parameter){ }

    protected override void SetRules(int parameter)
    {
        int x = 0;
        x = 1 + 3;

        Console.WriteLine(String.Concat("This is the derivated2 with x: ", x, "; _parameter: ", parameter));
    }
}
public static void Main()
{
    Derivated2 _class1 = new Derivated2(2);
}

正如您所说的,每次想要创建一个新类时都必须调用SetRules,这并不是很好,这意味着您不必这样做(快速将其组合在一起,因此您需要对其进行修复)

代码语言:javascript
复制
public abstract class Generic
{
    public Generic()
    {
        Console.WriteLine("This is the generic");
    }

    public abstract void SetRules();
}

public sealed class Derivated2 : Generic
{
    int _param;

    public Derivated2(RulesWithParameters rules) {
        _param = rules.Parameter;
    }

    public override void SetRules()
    {
        int x = 0;
        x = 1 + 3;

        Console.WriteLine(String.Concat("This is the derivated2 with x: ", x, "; _parameter: ", _param));
    }
}
public void Main()
{
    var rules = new RulesWithParameters{
        Parameter = 5
    };
    var _class1 = FactoryMethod<Derivated2>(rules);

    var _class2 = FactoryMethod<Derivated1>(null);
}

public class Derivated1 : Generic
{
    public Derivated1(Rules rules)
    {

    }
    public override void SetRules()
    {
        Console.WriteLine("This is the derivated1");
    }
}
public class Rules
{
    public string RuleName {get; set;}
}

public class RulesWithParameters : Rules{
    public int Parameter { get; set;}
}

public Generic FactoryMethod<T>(Rules rules) where T : Generic
{
    T instance = (T)Activator.CreateInstance(typeof(T), rules);;
    instance.SetRules();
    return instance;
}
票数 1
EN

Stack Overflow用户

发布于 2019-01-02 21:35:34

我猜C#中的构造函数不是多态的,所以你不能从你的构造函数中调用可覆盖的方法。您可以阅读以下文档:MSDN article

此外,在我看来,通常使用这种方法是一种糟糕的做法。抽象类的构造函数不知道你的子类的实现细节,也不应该知道,所以把Derivated2的初始化放在那里是不正确的。尝试将初始化代码放在其他地方。

票数 0
EN

Stack Overflow用户

发布于 2019-01-02 23:43:28

如果SetRules方法可以是静态的,而不是实例,也许您可以添加一个静态构造函数,并在该构造函数中调用SetRules方法。如果不是这样,工厂的想法似乎是最好的干净方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54007121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档