2013-02-28 70 views
1

我有这段代码,我觉得可以清理(我可能是错的),但我想看看是否有人有一个建议,我可以改变这是“更好”重构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); 
     } 
+0

我觉得使用它已经足够了。 – Stepo 2013-02-28 19:49:30

+0

至少,执行'getExt = getExt.ToLower()'并从条件中移除冗余etensions。 – 2013-02-28 20:05:31

回答

1

以下可能最初是更多的代码,但可以更好地扩展。

之外的方法:

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); 
    } 
15

地图扩展处理的是这样的情况下,标准的方法:

// 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); 
+2

我想补充一点,因为文件名不区分大小写,所以扩展名不区分大小写。即'新字典<字符串,动作>(StringComparer.OrdinalIgnoreCase)' – 2013-02-28 20:01:22

+0

对于密钥值而言,列表“”而不是“字符串”会更有意义吗?这是为了防止您希望多个分机进行相同的操作。 – gunr2171 2013-02-28 20:10:37

+0

@ gunr2171不,使用'List '作为关键是没有意义的,它实际上会破坏使用'Dictionary'的目的。在使用'List '时,您会使查找速度变慢,因为您需要检查每个密钥,直到找到包含所需扩展名的密钥,然后使用该密钥返回该值。 – 2013-02-28 20:31:40

4

你可以做这样的事情

switch (getExt.ToUpper()) 
    {  
     case "JPG":  
     case "PNG": 
.... 
1

如果您正在寻找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); 
    } 
} 
+1

今天我学到了新东西。哇!这看起来非常整齐,即使它比我开始的代码更多,但我也会尝试这一点。谢谢! – BB987 2013-02-28 20:13:16

+0

这是更多的代码,但增加了一些nore扩展,并达到盈亏平衡点。另外,由于数据驱动,它可以在运行时从外部文本文件加载。 – 2013-02-28 21:27:14

2

我觉得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); 
} 

此实现忽略大小写和文化,这是适当的文件名,但将不适合用于一般用途 - 所以真正的代码可能会提供指定文化和比较类型的重载。