С#。错误“具有不同签名的预期方法”。但显示相同的签名

问题描述 投票:0回答:1

我在

c_CriticalSituationHappened
 中有事件处理程序方法 
Program.cs

void c_CriticalSituationHappened(object sender, CriticalSituationGacEventArgs e)
{
    if (e.TypeDisrepair != TypeDisrepairGac.None)
    {
        start_time = DateTime.UtcNow;
        typeDisrepair = e.TypeDisrepair;
        WriteLine("Crit sit time: " + start_time);
        isStarted = true;
     }
}

如果我将其移至类库,我将导入它。

public class CorrectBehaviorCheck
{
    public void CriticalSituationHappened1(object sender, CriticalSituationGacEventArgs e)
    {
        if (e.TypeDisrepair != TypeDisrepairGac.None)
        {
            criticalSituationStartTime = DateTime.Now;
            TypeDisrepair = e.TypeDisrepair;
            Console.WriteLine("111");
            isStarted = true;
        }
    }
}

签名保持完全相同。 但是如果尝试一下

using cbc = mymodule.CorrectBehaviorCheck;
class Program{
    static void Main(string[] args){
        cbc a = new cbc();
        CriticalSituationHappened += a.CriticalSituationHappened1;
    }
}

代替

class Program{
    static void Main(string[] args){
        CriticalSituationHappened += c_CriticalSituationHappened;
    }
}

我有一个错误

Expected a method with 'void CriticalSituationHappened1(object?, CriticalSituationGacEventArgs)' signature
我做错了什么?两种方法具有相同的签名。为什么当我将方法放入类库时程序会中断?

在 Program.cs 中:

protected virtual void OnCriticalSituationHappened(CriticalSituationGacEventArgs e)
{
    EventHandler<CriticalSituationGacEventArgs> handler = CriticalSituationHappened;
    if (handler != null)
    {
        handler(this, e);
    }
}
public static event EventHandler<CriticalSituationGacEventArgs> CriticalSituationHappened;
c# events event-handling delegates class-library
1个回答
1
投票

您的错误是由于程序集中

CriticalSituationGacEventArgs
的多个定义而发生的。为了说明一点,在主程序集中(我们称之为
A
)我们有:

namespace A
{
    using cbc = B.CorrectBehaviorCheck;

    public class CriticalSituationGacEventArgs : EventArgs
    {
        public string Message { get; set; }
    }   

    public class Program
    {
        public static event EventHandler<A.CriticalSituationGacEventArgs> CriticalSituationHappened;

        public static void Main(string[] args)
        {
            cbc a = new cbc();
            CriticalSituationHappened += a.CriticalSituationHappened1;
            CriticalSituationHappened(null, new A.CriticalSituationGacEventArgs { Message = "Hello!" });
        }
    }
}

然后在外部组件中(我们称之为

B
)我们有:

namespace B
{
    public class CriticalSituationGacEventArgs : EventArgs
    {
        public string Message { get; set; }
    }
    
    public class CorrectBehaviorCheck
    {
        public void CriticalSituationHappened1(object sender, B.CriticalSituationGacEventArgs e)
        {
            Console.WriteLine("Listening in CorrectBehaviorCheck.CriticalSituationHappened1: " + e.Message);
        }
    }
}

这会导致错误

CriticalSituationHappened += a.CriticalSituationHappened1
。为了更多地理解这一点,我们可以更明确地将其定义为:

CriticalSituationHappened += (object sender, A.CriticalSituationGacEventArgs e) => a.CriticalSituationHappened1(sender, e);

这是尝试将

A.CriticalSituationGacEventArgs
传递给期望
B.CriticalSituationGacEventArgs
的参数,这会给出错误:

CS1503  Argument 2: cannot convert from 'A.CriticalSituationGacEventArgs' to 'B.CriticalSituationGacEventArgs'

因为编译器无法知道如何从一种类型转换为另一种类型。根据您的情况,有几种选择可以解决此问题:

1.手动转换事件参数

    CriticalSituationHappened += (sender, e) => 
        a.CriticalSituationHappened1(sender, new B.CriticalSituationGacEventArgs 
                                     { 
                                         Message = e.Message,
                                         // set other properties
                                     });

2.在共享程序集中定义一次事件参数

创建一个新项目(例如

MyEventArgs
)并在该项目中定义一次
CriticalSituationGacEventArgs
。那么
A
B
都可以在定义事件(在
MyEventArgs.CriticalSituationGacEventArgs
中)和处理事件(在
A
中)时引用
B
。这也避免了在
A
B
中定义单一类型的循环依赖。

© www.soinside.com 2019 - 2024. All rights reserved.