C# 编译时错误:无法从特定类型转换为泛型类型
我在if构造中调用NotifyObservators的行中得到了一个编译时错误,代码段如下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
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
派生的某种未指定类型。