pit*_*smx 6 c# generics polymorphism
我的层次结构TrendProviders用于提供来自不同来源的一系列数据点(趋势).
我已经开始使用通用接口:
public interface ITrendProvider<T> where T: TrendResult
{
IEnumerable<T> GetTrends();
}
Run Code Online (Sandbox Code Playgroud)
TrendResult 是一个结果类,包含获得的趋势数据和操作状态代码:
public class TrendResult
{
public TrendResult()
{
Points = new Dictionary<DateTimeOffset, decimal>();
}
public TrendResultCode Code { get; set; }
public string Name { get; set; }
public string Identifier { get; set; }
public Dictionary<DateTimeOffset, decimal> Points { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
TrendResultCode 如下:
public enum TrendResultCode
{
OK,
DataParseError,
NoData,
UnknownError
}
Run Code Online (Sandbox Code Playgroud)
还有两种类型(到目前为止)更详细的接口:
IFileTrendProvider - 用于从任何文件中获取趋势.
IServerTrendProvider - 用于从远程服务器获取趋势,例如使用FTP.
IFileTrendProvider 是这样的:
public interface IFileTrendProvider : ITrendProvider<TrendResult>
{
IFileReader FileReader {get; set}
FileTrendDiscoveryPattern Pattern {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
IServerTrendProvider 是这样的:
public interface IServerTrendProvider : ITrendProvider<TrendResult>
{
IClient Client { get; set; }
Dictionary<string, string[]> RequestedServerTrendIDs { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
实现接口的具体类如下:
其中FileTrend一种:
public class GenericFileTrendProvider : IFileTrendProvider<TrendResult>
{
public GenericFileTrendProvider() { }
public IFileReader FileReader {get; set}
public FileTrendDiscoveryPattern Pattern {get; set;}
public IEnumerable<TrendResult> GetTrends()
{
// Some code to obtain trends from file using FileReader
}
}
Run Code Online (Sandbox Code Playgroud)
其中一种ServerTrend类型:
public class ServerATrendProvider : IServerTrendProvider<TrendResult>
{
public ServerATrendProvider () { }
public IClient Client { get; set; }
public Dictionary<string, string[]> RequestedServerTrendIDs { get; set;}
public IEnumerable<TrendResult> GetTrends()
{
// Some code to obtain trends from remote server using Client
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我想要实现的目标以及我需要您的帮助和建议的地方:
在IFileReader推出了自己的错误代码:
public enum FileReadResultCode
{
OK,
FileAlreadyOpen,
FileNotFound,
UnknownError
}
Run Code Online (Sandbox Code Playgroud)
IClient 还介绍了其具体的操作错误代码:
public enum ClientCode
{
OK,
InvalidCredentials,
ResourceNotFounds,
UnknownError
}
Run Code Online (Sandbox Code Playgroud)
作为两者:IFileReader并且IClient还返回自己的错误代码,我怎么能在方法TrendResult返回的对象中引入它们GetTrends(),这样最终还会有一些关于"内部"错误的信息,而不仅仅是TrendResult特定的错误?
我需要一些灵活的解决方案-我在想继承TrendResult和创造FileTrendResult,并ServerTrendResult为每一个具体的供应商,同时也定义了两种特定的错误枚举,使他们返回自己的结果类型,但它可以在一些其他的方式来完成?
您可以更改类以存储异常列表并删除枚举,而不是在枚举中预先定义可能的错误列表(TrendResultCode、FileReadResultCode、 、 ...):ClientCodeTrendResult
public class TrendResult
{
// ...
// public TrendResultCode Code { get; set; }
public IEnumerable<Exception> Errors { get; set; }
// ...
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以存储错误的完整信息,包括堆栈跟踪和其他有价值的信息(如果单个问题中有多个问题,则可以存储多个错误的信息TrendResult)。即使对于意外错误,您也可以存储详细信息,而不是出现难以追踪的未知错误。
如果 a 的 TrendResult枚举中没有任何项目,则没有问题。否则,您可以将信息写入日志。
该实现遵循开放/关闭原则,因此您不必更改处理TrendResults新情况导致错误的实现。
对于您的业务异常,例如解析错误,您应该创建特定的异常类型,以便稍后能够根据错误的类型来分析这些错误。