如何强迫他人服从子类的特定布局?

时间:2015-06-08 14:51:33

标签: c# oop reflection

我有一个抽象类如下:

public abstract class Node
{
    public abstract void run();
}

有些子节点可能有多个属性作为输入和输出。但是所有操作都是在每个Node应该实现的run()方法中完成的。例如,绘制线的节点可能是这样的:

public class LineNode : Node
{
    [Input]
    public Point a;
    [Input]
    public Point b;
    [Output]
    public Line line;
    public override void run()
    {
        line = new Line(a, b);
        // draw line ...
    }
}

[AttributeUsage(AttributeTargets.Field)]
public class Input : System.Attribute
{

}
[AttributeUsage(AttributeTargets.Field)]
public class Output : System.Attribute
{

}

如您所见,我没有关于儿童班级领域的任何先前信息。 **要使节点成为常规中的有效节点,只需要至少有一个输出。** 我想强制所有其他用户在其节点中至少有一个输出我可以通过查找应用[Output]属性的字段来找到它。 这可能吗?
如果是这样,这是最好的方式吗?

感谢您的帮助

Here提出了同样的问题,但建议的解决方案在运行时解决了这个问题。我正在寻找面向对象的解决方案。哪一个更合乎逻辑?

3 个答案:

答案 0 :(得分:3)

你可以做这样的事情

public interface IRunnable<T>
{
    T Run();
}

然后,实现此接口的每个类都必须提供此run方法并返回(强类型化)结果。

或者如果run方法没有返回结果

public interface IRunnable<T>
{
    void Run();
    T Value {get;}
}
public class LineNode : IRunnable<Line>
{
    [Input]
    public Point a;
    [Input]
    public Point b;

    private Line line;
    public Line Value { get{return line;}}
    public override void run()
    {
    line = new Line(a, b);
    // draw line ...
    }

}

答案 1 :(得分:3)

在基类中定义类似的内容:

public abstract class Node
{
    [Output]
    public abstract object DefaultOuptut;
    public abstract void run();
}

现在您的线类可能如下所示:

public class LineNode : Node
{
    [Input]
    public Point a;
    [Input]
    public Point b;
    [Output]
    public Line line;
    [Output]
    public override object DefaultOutput { get { return line; } }

    public override void run()
    {
        line = new Line(a, b);
        // draw line ...
    }
}

您也可以在默认对象上使用一些通用类型:

public abstract class Node<T>
{
   [Output]
   public abstract T DefaultOutput;
   public abstract void run();
}

这仍然允许其他输出不是T s。

答案 2 :(得分:1)

如何使用接口IOutputDefinition并在ICollection<IOutputDefinition>类中定义抽象Node。所有实施者都必须填写此内容,以使您的代码能够确定实施将产生哪些输出。

您可以定义任何元数据属性,例如Name,Output-Type,...甚至是包含接口输出的Getter-Expression的属性