C# 编译时错误:无法从特定类型转换为泛型类型

C# 编译时错误:无法从特定类型转换为泛型类型,c#,generics,c#-3.0,C#,Generics,C# 3.0,我在if构造中调用NotifyObservators的行中得到了一个编译时错误,代码段如下 public class ExternalSystem<TEmployee, TEventArgs> : ISubject<TEventArgs> where TEmployee : Employee where TEventArgs : EmployeeEventArgs { protected List<IObserver<TEventArg

我在if构造中调用NotifyObservators的行中得到了一个编译时错误,代码段如下

public class ExternalSystem<TEmployee, TEventArgs> : ISubject<TEventArgs>
    where TEmployee : Employee
    where TEventArgs : EmployeeEventArgs
{
    protected List<IObserver<TEventArgs>> _observers = null;
    protected List<TEmployee> _employees = null;

    public virtual void AddNewEmployee(TEmployee employee)
    {
        if (_employees.Contains(employee) == false)
        {
            _employees.Add(employee);

            string message = FormatMessage("New {0} hired.", employee);

            if (employee is Executive)
                NotifyObservers(new ExecutiveEventArgs { e = employee, msg = message });
            else if (employee is BuildingSecurity)
                NotifyObservers(new BuildingSecurityEventArgs { e = employee, msg = message });
        }
    }

    public void NotifyObservers(TEventArgs args)
    {
        foreach (IObserver<TEventArgs> observer in _observers)
            observer.EmployeeEventHandler(this, args);
    }
}
公共类外部系统:ISubject
TEmployee在哪里:雇员
其中TEventArgs:EmployeeEventArgs
{
受保护列表_=null;
受保护列表_employees=null;
公共虚拟void AddNewEmployee(TEmployee员工)
{
if(_employees.Contains(employees)=false)
{
_employees.Add(employees);
string message=FormatMessage(“New{0}hired.”,employee);
if(员工为高管)
NotifyObservers(新的ExecutiveEventArgs{e=employee,msg=message});
else if(员工正在构建安全)
NotifyObservers(new BuildingSecurityEventArgs{e=employee,msg=message});
}
}
公共观察者(TEventArgs args)
{
foreach(IObserver观察员在_观察员中)
observer.EmployeeEventHandler(此参数为args);
}
}
我收到的错误是:

匹配的最佳重载方法 'ExternalSystem.NotifyObservers(TEventArgs)' 有一些无效的参数。不能 从“ExecutiveEventArgs”转换为 “TEventArgs”

我使用Visual Studio 2008 Express Edition在C#3.0中编译了这篇文章

现在,我已经通过将特定对象实例化分支到重写方法(如下面给出的代码片段)来绕过这个问题,但我需要理解错误发生的原因。我认为编译器可以在上述情况下推断类型层次结构

public class ExternalSystem<TEmployee, TEventArgs> : ISubject<TEventArgs>
    where TEmployee : Employee where TEventArgs: EmployeeEventArgs
{

protected List<IObserver<TEventArgs>> _observers = null;
protected List<TEmployee> _employees = null;

protected virtual void AddNewEmployee(TEmployee employee)
{
    if (_employees.Contains(employee) == false)
    {
        _employees.Add(employee);

        string message = FormatMessage("New {0} hired.", employee);

        NotifyObservers(GetEventArgs(employee, message));
    }
}


protected virtual TEventArgs GetEventArgs(TEmployee employee, string message)
{
    return default(TEventArgs);
}

public void NotifyObservers(TEventArgs args)
{
    foreach (IObserver<TEventArgs> observer in _observers)
        observer.EmployeeEventHandler(this, args);
}
}

public class SecuritySystem : 
ExternalSystem<BuildingSecurity, BuildingSecurityEventArgs>
{
    public SecuritySystem() : base() { }

protected override BuildingSecurityEventArgs GetEventArgs(BuildingSecurity employee, string message)
{
    return new BuildingSecurityEventArgs { msg = message, e = employee };
}

public void HireSecurityGuard(BuildingSecurity buildingSecurity)
{
    this.AddNewEmployee(buildingSecurity);
}

public void FireSecurityGuard(BuildingSecurity buildingSecurity)
{
    this.TerminateEmployee(buildingSecurity);
}
公共类外部系统:ISubject
where Temploye:Employee where TEventArgs:EmployeeEventArgs
{
受保护列表_=null;
受保护列表_employees=null;
受保护的虚拟void AddNewEmployee(TEmployee employee)
{
if(_employees.Contains(employees)=false)
{
_employees.Add(employees);
string message=FormatMessage(“New{0}hired.”,employee);
NotifyObservers(GetEventArgs(员工,消息));
}
}
受保护的虚拟TEventArgs GetEventArgs(TEmployee员工,字符串消息)
{
返回默认值(TEventArgs);
}
公共观察者(TEventArgs args)
{
foreach(IObserver观察员在_观察员中)
observer.EmployeeEventHandler(此参数为args);
}
}
公共类安全系统:
外部系统
{
public SecuritySystem():base(){}
受保护的覆盖BuildingSecurityEventTargets GetEventArgs(BuildingSecurityEmployee,字符串消息)
{
返回新的BuildingSecurityEventArgs{msg=message,e=employee};
}
public void HireSecurityGuard(建筑安全建筑安全)
{
此。添加新员工(楼宇安全);
}
公共消防安全警卫(建筑物安全建筑物安全)
{
本协议。终止员工(建筑安全);
}

}泛型参数
TEventArgs
将是某种特定类型,它是从
EmployeeEventArgs
派生的,但编译器直到后来才知道它将是哪种类型。因此,编译器不允许转换,因为它不知道转换是否有效


只是澄清一下,如果创建类型为
ExternalSystem
的对象,则
TEventArgs
将是该对象上下文中的
guantiorEventArgs
,并且对
NotifyObservers
的两个调用都将无效,因为
ExecutiveEventArgs
不是从
hanitorEventArgs

派生的,但是编译器不知道ExecutiveEventArgs是EmployeeEventArgs类型吗?BuildingSecurityEventArgs也是如此?@WC2,是的,但您试图将其传递给一个采用
TEventArgs
的方法,该方法不是
EmployeeEventArgs
,而是从
EmployeeEventArgs
派生的某种未指定类型。