gpt4 book ai didi

c# - 旧版 API 需要将回调名称作为字符串传递。我可以通过扩展方法改进该 API 吗?

转载 作者:行者123 更新时间:2023-11-30 22:43:51 24 4
gpt4 key购买 nike

我遇到了一个不使用 .NET 事件的遗留 API,而是要求我这样做:

// (first arg is System.Object, second arg is string, myFoo is of type Foo)
myFoo.AddCallback(this, "DoSomething(int)");

此 API 要求 DoSomethingthis 上的实例方法,并且它需要一个 int。

有没有一种方法可以强制此 API 以类型安全的方式使用?

更准确地说:我想为 Foo 编写一个扩展方法,它允许我使用 .NET 委托(delegate)而不是接收者-签名对调用 AddCallback。我在想象这样的事情:

// extension method definition
public static void AddCallback(this Foo foo, Action action)
{
foo.AddCallback(
FigureOutReceiverOf(action), // ?
FigureOutSignatureOf(action)); // ?
}

public static void AddCallback<T>(this Foo foo, Action<T> action)
{ ... } // and so on, for up to, say, 10 type-arguments

// usage:
myFoo.AddCallback(DoSomething)
// or even a lambda:
myFoo.AddCallback((i) => Console.WriteLine(i));

如果可以通过扩展方法破解来做到这一点,那会让我的生活更美好。另外,如果考虑到 C# 的功能,我只是感兴趣。

顺便说一下,遗留 API 称为 qt4dotnet。

最佳答案

使用 lambda 会很棘手 - 如果它捕获局部变量,它最终将成为不同类中的方法。当然,您可以检测到这一点,但它不是编译时安全的。

同样,签名部分也很有趣,因为如果它绝对是一个Action,则委托(delegate)没有参数。您不能只使参数 Delegate,否则方法组转换将不起作用...尽管您仍然可以调用

myFoo.AddCallBack(new Action<int>(MyMethodName));

另一种方法是产生一堆重载:

public static void AddCallback(this Foo foo, Action action)

public static void AddCallback<T>(this Foo foo, Action<T> action)

public static void AddCallback<T1, T2>(this Foo foo, Action<T1, T2> action)

它不会很优雅,但出于实际原因,您可能只需要几个。如果有任何方法返回值,您需要为 Func 返回类似的值。

传递具有多个操作的委托(delegate)还有一个额外的潜在问题……同样,您可以在编译时检查它。最后,您可能想要检查委托(delegate)的 Target 是否与 foo 参数相同。

解决了这些问题后,计算签名就相对简单了。您使用 Delegate.Method 属性,您可以从中获取名称和参数类型。如果库需要 "int" 而不是 "System.Int32" 等,那么您需要花点时间解决这个问题,但应该不会太糟糕。 (虽然这听起来确实是一个很奇怪的 API。)

关于c# - 旧版 API 需要将回调名称作为字符串传递。我可以通过扩展方法改进该 API 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3732939/

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