我可能需要一些帮助来进行编译。我只想传递类类型(SuccessEventArgs
)作为泛型类DebugEvent<TArgs> where TArgs : System.EventArgs
的参数。但由于某种原因,这不起作用..
namespace MyInterface
{
[Serializable]
public class SuccessEventArgs : System.EventArgs
{
public SuccessEventArgs(string data);
public byte[] GetData();
}
}
public class DebugEvent<TArgs> where TArgs : System.EventArgs
{
// ...
}
// ///////////////////////////////////////////////////////////////////////
public abstract class DebugEventHandler
{
protected DebugEvent<EventArgs> m_programmingSucceededEvent = null;
}
public class MyDebugEventHandler : DebugEventHandler
{
override public void InitializeEventHandler(int programmingSuccessCode, int breakepointReachedCode)
{
m_programmingSucceededEvent = new DebugEvent<SuccessEventArgs>(ref m_eventSignal, programmingSuccessCode, this);
}
}
错误消息:
Cannot implicitly convert type 'DebugEvent<SuccessEventArgs>' to 'DebugEvent<System.EventArgs>'
难道不可能吗?
答案 0 :(得分:4)
你想要的是协方差。有一些限制:
您可以像这样定义协变界面:
public interface IDebugEvent<out TArgs> where TArgs : System.EventArgs
但是请注意,如果你有一个采用TArgs
类型参数的方法,这将无法编译。提出示例为什么允许这会破坏类型安全性是相对简单的(例如,参见Jon Skeet对this question的回答)。如果这是您的要求,则必须重新考虑您的设计。
为了实际使用它,您必须使用接口类型的变量,而不是具体的类。所以你可以这样做:
IDebugEvent<EventArgs> m_programmingSucceededEvent = new DebugEvent<SuccessEventArgs>();
但不是:
DebugEvent<EventArgs> m_programmingSucceededEvent = new DebugEvent<SuccessEventArgs>();
答案 1 :(得分:1)
添加界面IDebugEvent<out T> where T : EventArgs
并拥有DebugEvent<T> : IDebugEvent<T> where T : EventArgs
然后以下内容将起作用:
IDebugEvent<EventArgs> m_programmingSucceededEvent = new DebugEvent<SuccessEventArgs>(ref m_eventSignal, programmingSuccessCode, this);
答案 2 :(得分:0)
您需要通过为TArgs
通用参数指定covariant来创建out
keyword接口以允许此操作:
public interface IDebugEvent<out TArgs> where TArgs : System.EventArgs
{ /* ... */ }
这仅在接口上受支持,因此您需要使DebugEvent
类实现协变接口:
public class DebugEvent<TArgs> : IDebugEvent<TArgs> where TArgs:System.EventArgs
{ /* ... */ }
这将允许您分配一个类型的实例,该类型的通用参数类型派生自基础System.EventArgs
类型。
IDebugEvent<EventArgs> evt = new DebugEvent<SuccessEventArgs>();