2013-04-02 36 views
0

我有以下抽象类:Action委托参数不匹配使用实现抽象类

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分配给增变器委托,但我无法。

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

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

具体来说,我得到以下错误:A method or delegate Mutators.VariantA(A)”参数不匹配委托System.Action<BaseClass>(BaseClass)' parameters (CS0123)

我明白Mutators.VariantA(A)需要A类型的对象,并采取了行动声明为接受BaseClass类型的输入,但是作为类A执行BaseClass我想我可以做到这一点?

从动态类型语言编辑我有一个艰难的时间去认真处理这样:(

与类型的合作有没有什么办法可以指向一个功能与抽象类型的输入这样一来?我需要看一些其他的设计模式?

感谢

回答

4

I understand that Mutators.VariantA(A) requires an object of type A, and the Action was declared to accept an input of type BaseClass, however as class A implements BaseClass I thought I would have been able to do this ?

绝对不是。

Action<BaseClass>必须能够接受任何BaseClass对象。因此,举例来说,如果你的代码是有效的,我就可以这样写:(其中BBaseClass派生另一个类)

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

BBaseClass派生的事实使得有效调用 - 但它不会帮助您的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”的价值观。但根据我的经验,这种通用嵌套非常迅速,非常混乱。

+0

'乔恩Skeet'你的方式toooooo'Fast'笑 – MethodMan

+0

我之所以有一个mutator是因为我需要能够让用户指定他们想要在一个拥有不同数据类型的类上执行什么类型的变化。我也希望能够设置自定义的增变函数。感谢您为我清除Jon。 – Sherlock

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 */ 
     } 
    }