我正在使用一个第三方库,它有一个事件\事件处理程序,我想将其转换为

系统ArgumentException-无法绑定到目标方法,因为其签名与委托类型的签名不兼容.

从…起

System.Private.CoreLib.dll!System.Reflection.RuntimeMethodInfo.CreateDelegateInternal(System.Type delegateType, object firstArgument, System.DelegateBindingFlags bindingFlags) Line 556    C#
    System.Private.CoreLib.dll!System.Reflection.RuntimeMethodInfo.CreateDelegate(System.Type delegateType, object target) Line 534 C#
    System.Reactive.dll!System.Reactive.ReflectionUtils.CreateDelegate<Test.TheDelegate>(object o, System.Reflection.MethodInfo method) Line 18 C#

If I remove the in 从…起 the arguments, It works as expected. I'm at a loss to understand why? Is even possible to do?

using System;
using System.Diagnostics;
using System.Reactive.Linq;

Test test = new();

Start();
test.TriggerEvent();
test.TriggerEvent();

void Start()
{
    Debug.WriteLine("Start");
    var o = Observable.FromEvent<Test.TheDelegate, SomeStruct>
        (h => test.TheEvent += h, 
         h => test.TheEvent -= h)
                      .Subscribe(OnNext);
}

void OnNext(SomeStruct s) => Debug.WriteLine("OnNext");

public class Test
{
    public delegate void TheDelegate(in SomeStruct o);

    // Without the in (or ref) keyword, no exception
    //public delegate void TheDelegate(SomeStruct o);

    public event TheDelegate? TheEvent;

    public void TriggerEvent()
    {
        SomeStruct s = new();
        TheEvent?.Invoke(s);
        Debug.WriteLine("Event Fired");
    }
}

public struct SomeStruct
{ }

推荐答案

我能够在运行时复制ArgumentException.要解决此问题,可以使用Observable.FromEvent重载,该重载有一个额外的conversion参数:

public static IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(
    Func<Action<TEventArgs>, TDelegate> conversion,
    Action<TDelegate> addHandler,
    Action<TDelegate> removeHandler);

用法:

var observable = Observable.FromEvent<Test.TheDelegate, SomeStruct>
(
    action => (in SomeStruct arg) => action(arg),
    h => test.TheEvent += h,
    h => test.TheEvent -= h
);
var subscription = observable.Subscribe(OnNext);

conversionAction<SomeStruct>转换为Test.TheDelegate.与简单的重载相反,转换的有效性在编译时判断.

Csharp相关问答推荐

WPF文本框点击鼠标 Select 内容

如何处理OpenTelegram中可以划分的大痕迹?

try 在C#中启动Tunnelbear.Exec

需要更改哪些内容才能修复被覆盖的财产中的无效警告CS 8765?

将修剪声明放入LINQ中

Monty Hall游戏节目模拟给我50/50的结果

C#相同名称的枚举方法和normal方法,参数类型不同

"virtual"修饰符对接口成员有什么影响?

实体核心框架--HasColumnType和HasPrecision有什么不同?

应用程序重新启动后,EFCore列表的BSON反序列化错误

使用C#HttpClient以多部分形式数据发送带有非ASCII文件名的文件的问题

在静态模式下实例化配置

由于POST中的应用程序/JWT,出现不支持的内容类型异常

在IAsyncEnumerable上先调用,然后跳过(1)可以吗?

在C#中,非静态接口方法的抽象和虚拟是冗余的吗?

Swagger没有显示int?可以为空

如何允许数组接受多个类型?

使用CollectionView时在.NET Maui中显示数据时出现问题

用MongoDB c#驱动程序删除和返回嵌套数组中的文档

如何将行添加到DataGrid以立即显示它?