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

时间:2010-05-31 09:33:37

标签: c# generics c#-3.0

我在if结构中调用NotifyObservers的行中使用以下相关代码段获得编译时错误。

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);
    }
}

我收到的错误是:

  

最佳重载方法匹配   '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);
}

}

1 个答案:

答案 0 :(得分:1)

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

为了澄清一下,如果你创建了ExternalSystem<Janitor, JanitorEventArgs>类型的对象,那么TEventArgs将在此对象的上下文中JanitorEventArgs,并且对NotifyObservers的两次调用都将无效,因为ExecutiveEventArgs并非来自JanitorEventArgs