我有以下抽象类:
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 delegateMutators.VariantA(A)的参数与委托System.Action<BaseClass>(BaseClass)' parameters (CS0123)不匹配
我知道Mutators.VariantA(A)需要一个A类型的对象,而操作被声明为接受BaseClass类型的输入,然而,由于类A实现了BaseClass,我认为我应该能够做到这一点?
来自动态类型语言的我很难用这种方式来处理类型:
有没有什么方法可以让我以这种方式指向一个带有抽象类型输入的函数?我需要看一些其他的设计模式吗?
谢谢
发布于 2013-04-03 03:11:01
我知道Mutators.VariantA( A )需要一个类型为A的对象,而
被声明为接受类型为BaseClass的输入,然而,由于类A实现了BaseClass,我认为我应该能够做到这一点?
绝对不是。
Action<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-03 03:13:56
我已经使用了您当前的示例,并将其中一个类的方法签名更改为以下内容,它可以正常工作
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 */
}
}https://stackoverflow.com/questions/15772310
复制相似问题