重构if-else语句检查不同的文件扩展名
我有这段代码,我觉得可以清理(我可能是错的),但我想看看是否有人有一个建议,我可以改变这是“更好”重构if-else语句检查不同的文件扩展名
string getExt = Path.GetExtension(DocumentUNCPath.Text);
var convertFileId = Guid.NewGuid();
var convertFilePath = @"c:\temp\" + convertFileId + ".pdf";
if (getExt == ".doc" || getExt == ".docx" || getExt == ".txt" || getExt == ".rtf")
{
WordToPdf(convertFilePath);
}
else if (getExt == ".xlsx" || getExt == ".xls")
{
ExcelToPdf(convertFilePath);
}
else if (getExt == ".jpg" || getExt == ".png" || getExt == ".jpeg" || getExt == ".JPG" || getExt == ".PNG")
{
ImgToPDF(convertFilePath);
}
以下可能最初是更多的代码,但可以更好地扩展。
之外的方法:
public static readonly List<string> WorkExtensions = new List<string> { ".doc", ".docx", ".txt", ".trf" };
public static readonly List<string> ExcelExtensions = new List<string> { ".xlsx", ".xls" };
public static readonly List<string> ImageExtensions = new List<string> { ".jpg", ".png", ".jpeg" };
里面的方法:
string getExt = Path.GetExtension(DocumentUNCPath.Text);
var convertFileId = Guid.NewGuid();
var convertFilePath = @"c:\temp\" + convertFileId + ".pdf";
getExt = getExt.ToLower();
if (WorkExtensions.Contains(getExt))
{
WordToPdf(convertFilePath)
}
else if (ExcelExtensions.Contains(getExt))
{
ExcelToPdf(convertFilePath);
}
else if (ImageExtensions.Contains(getExt))
{
ImgToPdf(convertFilePath);
}
地图扩展处理的是这样的情况下,标准的方法:
// populate with { ".doc", WordToPdf } and similar pairs
Dictionary<string, Action<string> > handlers = ...
// find and call handler by extension
// (use TryGetValue to check for existence if needed)
handlers[getExt](convertFilePath);
我想补充一点,因为文件名不区分大小写,所以扩展名不区分大小写。即'新字典>(StringComparer.OrdinalIgnoreCase)' – 2013-02-28 20:01:22
对于密钥值而言,列表“
@ gunr2171不,使用'List
你可以做这样的事情
switch (getExt.ToUpper())
{
case "JPG":
case "PNG":
....
如果您正在寻找extensiblity,你可以conisder是这样的:
public struct Converter {
public string Extension;
public Action<string> ConvertAction;
}
public static class Extensions {
static Action<string> WordToPdf = (s) => {;};
static Action<string> ExcelToPdf = (s) => {;};
static Action<string> ImgToPdf = (s) => {;};
public static IEnumerable<Converter> Converters = new List<Converter> {
new Converter {Extension = ".doc", ConvertAction = WordToPdf},
new Converter {Extension = ".docx", ConvertAction = WordToPdf},
new Converter {Extension = ".txt", ConvertAction = WordToPdf},
new Converter {Extension = ".rtf", ConvertAction = WordToPdf},
new Converter {Extension = ".xls", ConvertAction = ExcelToPdf},
new Converter {Extension = ".xlsx", ConvertAction = ExcelToPdf},
new Converter {Extension = ".jpg", ConvertAction = ImgToPdf},
new Converter {Extension = ".png", ConvertAction = ImgToPdf},
new Converter {Extension = ".jpeg", ConvertAction = ImgToPdf},
new Converter {Extension = ".doc", ConvertAction = ImgToPdf}
};
public void RunIt(string extension, string convertFilePath) {
extension = extension.ToLower();
var action = (from a in Converters
where a.Extension.Equals(extension)
select a.ConvertAction).First();
if (action != null) action(convertFilePath);
}
}
今天我学到了新东西。哇!这看起来非常整齐,即使它比我开始的代码更多,但我也会尝试这一点。谢谢! – BB987 2013-02-28 20:13:16
这是更多的代码,但增加了一些nore扩展,并达到盈亏平衡点。另外,由于数据驱动,它可以在运行时从外部文本文件加载。 – 2013-02-28 21:27:14
我觉得Dictionary<string, Action<string>>
以上答案是最优雅的答案,但为了完整起见,这里有一个解决方案通过串扩展:
public static class StringExt
{
public static bool MatchesAnyOf(this string text, params string[] targets)
{
return targets.Any(target => string.Compare(text, target, StringComparison.OrdinalIgnoreCase) == 0);
}
}
然后,你可以写这样的代码:
if (getExt.MatchesAnyOf(".doc", ".doxc", ".txt", ".rtf"))
{
WordToPdf(convertFilePath);
}
else if (getExt.MatchesAnyOf(".xlsx", ".xls"))
{
ExcelToPdf(convertFilePath);
}
else if (getExt.MatchesAnyOf(".jpg", ".png", ".jpeg", ".JPG", ".PNG")
{
ImgToPDF(convertFilePath);
}
此实现忽略大小写和文化,这是适当的文件名,但将不适合用于一般用途 - 所以真正的代码可能会提供指定文化和比较类型的重载。
我觉得使用它已经足够了。 – Stepo 2013-02-28 19:49:30
至少,执行'getExt = getExt.ToLower()'并从条件中移除冗余etensions。 – 2013-02-28 20:05:31