0

我有以下抽象类:

public abstract class BaseClass{
    public object contents { get; set; }
    public Action<BaseClass> mutator;
    public abstract void Initialise();
}

这将被几个类使用,这些类将覆盖Initialize为 分配值的方法,然后在特定时间点使用委托contents对其进行变异。mutator

我有以下静态类,每个方法都打算用作mutator

public static class Mutators{
    public static void VariantA(A inputObj){
        // inputObj.contents = something else
    }

    public static void VariantB(A inputObj) { } // etc. etc.
}

然后我有A类,它实现了BaseClass。我正在尝试将 Mutators.VariantA 分配给 mutator 代表,但我做不到。

public class A : BaseClass{
    public A(){
        mutator = Mutators.VariantA;
    }

    public override void Initialise(){
        /* set the value of contents property here */
    }
}

具体来说,我收到以下错误:A method or delegateMutators.VariantA(A)' parameters do not match delegateSystem.Action<BaseClass>(BaseClass)' parameters (CS0123)

我知道这Mutators.VariantA(A)需要一个类型的对象A,并且 Action 被声明为接受一个类型的输入BaseClass,但是作为类A实现BaseClass我认为我能够做到这一点?

来自动态类型语言,我很难掌握以这种方式处理类型的问题:(

有什么方法可以通过这种方式指向具有抽象类型输入的函数吗?我需要看看其他一些设计模式吗?

谢谢

4

2 回答 2

4

我知道 Mutators.VariantA(A) 需要 A 类型的对象,并且 Action 被声明为接受 BaseClass 类型的输入,但是当 A 类实现 BaseClass 时,我认为我能够做到这一点?

绝对不。

AnAction<BaseClass>必须能够接受任何 BaseClass对象。因此,例如,如果您的代码有效,我将能够编写:

Action<BaseClass> mutator = Mutators.VariantA;
mutator.Invoke(new B());

(从哪里B派生的另一个类BaseClass。)

B派生自的事实BaseClass使其对调用有效- 但它不会帮助您的VariantA方法很好地工作。

目前还不清楚为什么你在这里一个突变体——我强烈怀疑你应该BaseClass从它的突变中抽象出来。我仍然没有遵循您想要实现的目标,但是这种设计模式不会帮助您以类型安全的方式实现目标。

可以写:

public abstract class BaseClass<T> where T : BaseClass<T> {
    public object Contents { get; set; }
    public Action<T> Mutator { get; set; }
    public abstract void Initialise();
}

... 然后:

public class A : BaseClass<A> {
    public A() {
        Mutator = Mutators.VariantA;
    }
}

...那样你就会写一些可以改变“A”值的东西。但以我的经验,这种通用嵌套变得非常混乱,非常快。

于 2013-04-02T19:11:01.427 回答
1

我已经使用了您当前的示例并将其中一个类的方法签名更改为以下内容,并且可以正常工作

    public abstract class BaseClass
    {
        public object contents { get; set; }
        public Action<BaseClass> mutator;
        public abstract void Initialise();
    }
    public static class Mutators
    {
        public static void VariantA(BaseClass baseClass)
        {
            // inputObj.contents = something else
        }

        public static void VariantB(A inputObj) { } // etc. etc.
    }
    public class A : BaseClass
    {
        public A()
        {
            mutator = Mutators.VariantA;
        }

        public override void Initialise()
        {
            /* set the value of contents property here */
        }
    }
于 2013-04-02T19:13:56.203 回答