使用变量代替函数名称
我现在正在使用以下内容:
foreach (string file in files) { switch (filetype.Value) { case "ReadFile": ReadFile(file); break; case "ReadMSOfficeWordFile": ReadMSOfficeWordFile(file); break; case "ReadMSOfficeExcelFile": ReadMSOfficeExcelFile(file); break; case "ReadPDFFile": ReadPDFFile(file); break; } }
它有效,但感觉有点不对劲。 Python的方式更像是这样的:
foreach string file in files: filetype.Value(file)
我很难想象C#不能做这样的事情。 可能是我的Google技能不好,但我似乎无法弄明白。
解
public static readonly IDictionary<string, Action> FileTypesDict = new Dictionary<string,Action> { {"*.txt", ReadFile}, {"*.doc", ReadMSOfficeWordFile}, {"*.docx", ReadMSOfficeWordFile}, {"*.xls", ReadMSOfficeExcelFile}, {"*.xlsx", ReadMSOfficeExcelFile}, {"*.pdf", ReadPDFFile}, };
foreach (KeyValuePair<string, Action> filetype in FileTypesDict) { string[] files = Directory.GetFiles(FilePath, filetype.Key, SearchOption.AllDirectories); //System.Reflection.MethodInfo ReadFileMethod = ReadFile.GetType().GetMethod(filetype.Value); foreach (string file in files) { FileTypesDict[filetype.Key](file); } }
您可以使用委托进行一些准备工作,如下所示:
private static readonly IDictionary> actionByType = new Dictionary> { {"ReadFile", ReadFile} , {"ReadMSOfficeWordFile", ReadMSOfficeWordFile} , {"ReadMSOfficeExcelFile", ReadMSOfficeExcelFile} , {"ReadPDFFile", ReadPDFFile} };
在需要调用您的操作时,请按以下步骤操作:
actionByType[actionName](file);
您可以使用委托:
Action action; switch (filetype.Value) { case "ReadFile": action = ReadFile; break; case "ReadMSOfficeWordFile": action = ReadMSOfficeWordFile; break; case "ReadMSOfficeExcelFile": action = ReadMSOfficeExcelFile; break; case "ReadPDFFile": action = ReadPDFFile; break; default: throw new NotImplementedException("Unhandled file type '"+filetype.Value+"'."); } foreach (string file in files) { action(file); }
您可以保留委托Dictionary
,这是最简单的方法:
Dictionary> fileReaders = new Dictionary>() { {"ReadFile", ReadFile}, {"ReadOfficeWordFile", ReadOfficeWordFile}, {"ReadOfficeExcelFile", ReadOfficeExcelFile}, {"ReadPDFFile", ReadPDFFile} };
然后这样称呼它:
fileReaders[fileType.Value](file);
根据您的方法返回的内容,您可能必须更改委托的类型(例如, Action
表示void something(string someparam)
作为方法签名)。
我相信你正在寻找的东西需要对你的代码进行一些重构。
所有“案例”(TextFile,MSOfficeWordFile,MSOfficeExcelFile,PdfFile)都应该是它们自己的类,它们实现了单个接口。
您的界面应命名为“IReadableFile”,并指定名为“ReadFile()”的方法。
每个类都应该有自己的“ReadFile()”实现
例:
public interface IReadableFile { void ReadFile(); }
public class MSOfficeWordFile : IReadableFile { public void ReadFile() { ReadMSOfficeWordFile(file); } }
foreach(IReadableFile file in files) file.ReadFile();
代码可能包含一些错误,但我希望你能得到这个想法。
你也可以使用reflection(如果你可以带来不同的开销)检查这个解决方案
希望有所帮助
如果您正在寻找避免将方法名显式映射到字符串值的方法,可以使用reflection来进行动态方法调用(假设filetype.Value的类型为String
)
String method_name = String.Empty; foreach (string file in files) { method_name = filetype.Value; System.Reflection.MethodInfo method = this.GetType().GetMethod(method_name); method.Invoke(this, new object[]{file}); }