基于C#中基类中的动态参数调用在子类中查找方法
本文关键字:子类 查找 调用 方法 动态 基类 基于 参数 | 更新日期: 2023-09-27 18:28:03
我有一个基类,它有一个接受接口的方法。我想在子类中找到最匹配这个接口的方法。例如:
abstract class Base<T>
{
public T Get(IParam parameter){
return Provide(parameter as dynamic);
}
public abstract T Provide(IParam parameter);
}
class Impl<string> : Base<string>
{
public string Provide(IParam parameter)
{
return "default value";
}
public string Provide(ParamImplementation1 parameter)
{
return "value for implementation 1";
}
public string Provide(ParamImplementation2 parameter)
{
return "value for implementation 2";
}
}
不幸的是,每次都会返回默认值。当实际实现在子类中时,dynamic关键字似乎不起作用。有什么办法让它发挥作用吗?
因此,解决方案似乎是将this
强制转换为dynamic
,如下所示:
abstract class Base<T>
{
public T Get(IParam parameter){
return (this as dynamic).Provide(parameter as dynamic);
}
public abstract T Provide(IParam parameter);
}
class Impl<string> : Base<string>
{
public string Provide(IParam parameter)
{
return "default value";
}
public string Provide(ParamImplementation1 parameter)
{
return "value for implementation 1";
}
public string Provide(ParamImplementation2 parameter)
{
return "value for implementation 2";
}
}
为什么不检查Provide
方法重写中parameter
的真实类型?
private abstract class Base<T>
{
public T Get(IParam parameter)
{
return Provide(parameter);
}
public abstract T Provide(IParam parameter);
}
private class Impl : Base<string>
{
public override string Provide(IParam parameter)
{
if (parameter is ParamImplementation1)
return "value for implementation 1";
if (parameter is ParamImplementation2)
return "value for implementation 2";
return "default value";
}
}
您可以在默认的provide(IParam param)
方法中处理它。
private readonly IDictionary<Type, MethodInfo> _methods;
public Impl() {
var methods = this.GetType().GetMethods(
BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Instance |
BindingFlags.FlattenHierarchy);
var provide = methods
.Where(m => m.Name.Equals("Provide", StringComparison.Ordinal) && m.GetParameters().Length == 1)
.ToList();
_methods = when.ToDictionary(m => m.GetParameters().First().ParameterType, m => m);
}
public string Provide(IParam param) {
MethodInfo methodInfo;
if (dictionary.TryGetValue(param.GetType(), out methodInfo)) {
return methodInfo.Invoke(this, new object[] { param });
}
return "default value";
}
因此,您可以检查类中名称为Provide
的方法,并将其保存在字典中。出于性能原因,我会将此词典存储在类成员中。然后,您可以询问字典是否有适合您特定参数类型的方法。
使用此技术,在添加新的Provide()
实现时不必更改其他方法或切换/case语句。