我正在编写一个带有抽象方法的抽象类(因此,从它继承的所有类都必须实现该方法)。但是,我不想指定该方法必须使用的参数,因为每个方法可能采用不同的参数或不采用任何参数。只有名称和返回值应该相同。
有没有办法在 C# 中做到这一点?
感谢您的帮助!
不,这样做是没有意义的。如果您没有声明参数,则您将无法调用仅提供对基类的引用的方法。这就是抽象方法的意义所在:让调用者不用关心具体的实现,而是给他们一个 API 来使用。
如果调用者需要知道确切的方法签名,那么你已经将该调用者绑定到具体的实现,使得抽象本质上毫无用处。
也许如果您可以提供更多细节,我们可以建议更合适的方法?例如,您可以使类型通用:
public class Foo<T>
{
public abstract void Bar(T t);
}
具体子类型可以也是通用的,或者例如源自
Foo<string>
。
不。你为什么需要它?也许命令设计模式可以在这里提供帮助。
你想要做的是代码味道。
更好的模式是让抽象类实现 ISupportInitialize,然后有一个抽象
Act()
方法。
这个想法是,在调用
BeginInit
和 EndInit
之间,当您的孩子键入准备采取行动时,收集您试图塞入随机类型和数量的参数中的不同信息。配置完成后,调用 EndInit
(此处验证)可以调用摘要 Act()
。
另外,请不要这样做:
public abstract void Act(params object[] arguments);
如果你做这样的事情,人们会追捕你。
不,没有。
要重写方法,您必须匹配方法签名。这包括方法名称和格式参数。
这个问题需要更多关于在这里做什么的例子,所以这是一个。我的具体场景是我从工厂获取抽象
ActionBaseClass
的具体实例,并且我需要使用特定于我的场景的参数在该实例上调用一些 DoAction()
函数。
以下是类的定义:
public abstract class ActionsClassBase
{
// Hint for the funciton we want on our concrete instances
public virtual bool DoAction() =>
throw new NotImplementedException();
}
public class MyConcreteInstance : ActionsClassBase
{
public bool DoAction(object a, string b, int c)
{
// your implmentation
}
}
观察
MyConcreteInstance.DoAction()
如何具有特定场景所需的参数。请注意,此函数不会实现/覆盖 ActionsBaseClass.DoAction
,在这种情况下,这只是向开发人员提示其希望具体类型实现的函数名称。
我从工厂获取实例是这样的:
var myA = somethingA;
var myB = somethingB;
var myC = somethingC;
// `SomeFactory.Create` returns the instance as `ActionsClassBase`
var myAction = SomeFactory.Create(typeof(MyConcreteInstance)) as MyConcreteInstance;
我正在转换为具体实例的类型,因为在这种情况下我知道它应该是什么,并且我有需要在其上调用
DoAction
的参数值(myA
、myB
和 myC
)
)。我们需要一些对象来保存这些参数并将它们传递到具体实例的操作中。
这里的技巧是创建一个解析器对象来为我们完成工作。我们为所有要使用的具体实例创建一个抽象解析器,并为我们的特定类创建一个特定解析器:
public abstract class DoActionResolver
{
// Function with the same parameters and return type as in `AbstractClassBase`
public abstract bool DoAction();
}
public class MyConcreteInstanceDoActionResolver : DoActionResolver
{
MyConcreteInstance _instance;
object _a;
string _b;
int _c;
public MyConcreteInstanceDoActionResolver(MyConcreteInstance instance, object a, string b, int c)
{
_instance = instance
_a = a;
_b = b;
_c = c;
}
public override bool DoAction() =>
_instance.DoAction(_a, _b, _c);
}
现在我可以创建解析器的一个实例,我可以使用我需要的参数调用
DoAction
:
// I already know what I need to call the action with on my instance in this scenario.
// Lets assume we are storing them in variables with names myA, myB, and myC
var myActionResolver = new MyConcreteInstaceDoActionResolver(myAction, myA, myB, myC);
最后,我可以通过我的解析器调用该操作:
myActionResolver.DoAction();