我的控制台应用程序必须能够从两个必须实现名为IDataSource
的接口的不同数据源中获取数据。收到数据时,dataSource对象必须引发名为OnHistoricalDataReceived
的事件。
我创建了EventArgs
:
public class HistoricalDataReceivedEventArgs : EventArgs
{
public IDataSource DataSource {get; set;}
public string Symbol {get; set;}
public List<DailyPrice> Data {get;set;}
public HistoricalDataReceivedEventArgs(IDataSource dataSource, string symbol, List<DailyPrice> data)
{
DataSource = dataSource;
Symbol = symbol;
Data = data;
}
}
我创建了界面IDataSource
:
public interface IDataSource
{
event EventHandler<HistoricalDataReceivedEventArgs> OnHistoricalDataReceived;
List<DailyPrice> RequestHistoricalData(string symbol, List<PriceField> fields, DateTime? firstDate=null, DateTime? lastDate=null);
}
然后我创建了两个简单的类,一个用于Bloomberg,另一个用于路透社:
public class Bloomberg: IDataSource
{
public delegate void HistoricalDataReceivedEventRaiser(HistoricalDataReceivedEventArgs args);
public event HistoricalDataReceivedEventRaiser OnHistoricalDataReceived;
public List<DailyPrice> RequestHistoricalData(string symbol, List<PriceField> fields, DateTime? firstDate=null, DateTime? lastDate=null)
{
var data = new List<DailyPrice>();
// ... get the data
var args = new HistoricalDataReceivedEventArgs(dataSource: this, symbol: symbol, data: data);
if (OnHistoricalDataReceived!=null)
{
OnHistoricalDataReceived(args);
}
}
}
public class Reuters: IDataSource
{
public delegate void HistoricalDataReceivedEventRaiser(HistoricalDataReceivedEventArgs args);
public event HistoricalDataReceivedEventRaiser OnHistoricalDataReceived;
public List<DailyPrice> RequestHistoricalData(string symbol, List<PriceField> fields, DateTime? firstDate=null, DateTime? lastDate=null)
{
var data = new List<DailyPrice>();
// ... get the data
var args = new HistoricalDataReceivedEventArgs(dataSource: this, symbol: symbol, data: data);
if (OnHistoricalDataReceived!=null)
{
OnHistoricalDataReceived(args);
}
}
}
所有代码都工作如果我避免将这一行放在我的界面中:
event EventHandler<HistoricalDataReceivedEventArgs> OnHistoricalDataReceived;
但我希望实现接口的每个对象都会在检索数据时引发此事件。
如果我尝试编译编译器抱怨:
'Bloomberg'没有实现接口成员'IDataSource.OnHistoricalDataReceived'。 'Bloomberg.OnHistoricalDataReceived'无法实现 'IDataSource.OnHistoricalDataReceived'因为它没有 匹配'EventHandler'的返回类型。
'路透社'没有实现接口成员'IDataSource.OnHistoricalDataReceived'。 'Reuters.OnHistoricalDataReceived'无法实现 'IDataSource.OnHistoricalDataReceived'因为它没有 匹配'EventHandler'的返回类型。
我尝试了很多变化而没有任何成功。在我的界面中指定我想要OnHistoricalDataReceived
事件的正确方法是什么?
答案 0 :(得分:5)
您需要在类中实现事件,而是创建两个新的委托类型并将它们用作事件的类型。
您实现事件就像在界面中声明它一样:
public class Bloomberg: IDataSource
{
public event EventHandler<HistoricalDataReceivedEventArgs> OnHistoricalDataReceived;
public List<DailyPrice> RequestHistoricalData(string symbol, List<PriceField> fields, DateTime? firstDate=null, DateTime? lastDate=null)
{
var data = new List<DailyPrice>();
// ... get the data
var args = new HistoricalDataReceivedEventArgs(dataSource: this, symbol: symbol, data: data);
if (OnHistoricalDataReceived!=null)
{
OnHistoricalDataReceived(this, args); // use "this" as sender
}
}
}
public class Reuters: IDataSource
{
public event EventHandler<HistoricalDataReceivedEventArgs> OnHistoricalDataReceived;
public List<DailyPrice> RequestHistoricalData(string symbol, List<PriceField> fields, DateTime? firstDate=null, DateTime? lastDate=null)
{
var data = new List<DailyPrice>();
// ... get the data
var args = new HistoricalDataReceivedEventArgs(dataSource: this, symbol: symbol, data: data);
if (OnHistoricalDataReceived!=null)
{
OnHistoricalDataReceived(this, args); // use this as sender
}
}
}
注意(在C#6中)你可以这样做:
OnHistoricalDataReceived?.Invoke(this, args);
这是线程安全的。如果在空检查后再次取消该事件,则当前代码可能会中断。
在C#6之前你应该这样做:
var handler = OnHistoricalDataReceived; // save the reference
if (handler != null) handler(this, args); // use the local (unchanged) variable
答案 1 :(得分:0)
请将您的界面更改为:
public interface IDataSource
{
event HistoricalDataReceivedEventRaiser OnHistoricalDataReceived;
List<DailyPrice> RequestHistoricalData(string symbol, List<PriceField> fields, DateTime? firstDate=null, DateTime? lastDate=null);
}