gpt4 book ai didi

C# 无法从泛型方法调用重载的非泛型方法

转载 作者:可可西里 更新时间:2023-11-01 03:08:46 25 4
gpt4 key购买 nike

我有一些带有 foo 方法的遗留代码,它有 700 多个重载:

[DllImport("3rdparty.dll")]
protected static extern void foo(int len, ref structA obj);
[DllImport("3rdparty.dll")]
protected static extern void foo(int len, ref structB obj);
[DllImport("3rdparty.dll")]
protected static extern void foo(int len, ref structC obj);
//and 700 similar overloads for foo...

我想通过使用泛型的单个方法公开这些重载方法:

public void callFoo<T>(int len)
where T : new() //ensure an empty constructor so it can be activated
{
T obj = Activator.CreateInstance<T>(); //foo expects obj to be empty, and fills it with data
foo(len, ref obj);

//...do stuff with obj...
}

不幸的是,这会返回错误:“‘foo(int, ref StructA)’的最佳重载方法匹配有一些无效参数”和“无法从‘ref T’转换为'ref StructA'”。

是否有一种优雅的方式来实现这一点?

最佳答案

我希望 dynamic 在这里有所帮助,但它不喜欢 ref。无论如何,反射应该起作用:

public T callFoo<T>(int len)
where T : new() //ensure an empty constructor so it can be activated
{
T obj = new T();
GetType().GetMethod("foo", BindingFlags.Instance | BindingFlags.NonPublic,
null, new[] { typeof(int), typeof(T).MakeByRefType() }, null)
.Invoke(this, new object[] { len, obj });
return obj;
}

这是一个只做一次反射的优化版本;应该更快:

class Test
{

protected void foo(int len, ref classA obj){}
protected void foo(int len, ref classB obj){ }
protected void foo(int len, ref classC obj){}
static readonly Dictionary<Type, Delegate> functions;
delegate void MyDelegate<T>(Test arg0, int len, ref T obj);
static Test()
{
functions = new Dictionary<Type, Delegate>();
foreach (var method in typeof(Test).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance))
{
if (method.Name != "foo") continue;
var args = method.GetParameters();
if (args.Length != 2 || args[0].ParameterType != typeof(int)) continue;
var type = args[1].ParameterType.GetElementType();
functions[type] = Delegate.CreateDelegate(
typeof(MyDelegate<>).MakeGenericType(type), method);
}
}
public T callFoo<T>(int len)
where T : new() //ensure an empty constructor so it can be activated
{
T obj = new T();
Delegate function;
if (!functions.TryGetValue(typeof(T), out function)) throw new NotSupportedException(
"foo is not supported for " + typeof(T).Name);
((MyDelegate<T>)function)(this, len, ref obj);
return obj;
}
}

关于C# 无法从泛型方法调用重载的非泛型方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3905398/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com