Use variable in place of function name

后端 未结 6 1587
自闭症患者
自闭症患者 2021-02-09 13:16

I\'m using the following right now:

foreach (string file in files) {
    switch (filetype.Value) {
        case \"ReadFile\":
            ReadFile(file);
                


        
相关标签:
6条回答
  • 2021-02-09 13:24

    You can use a delegate:

    Action<string> 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);
    }
    
    0 讨论(0)
  • 2021-02-09 13:27

    If you're looking for a way to avoid the explicit mapping of method names to string values you could use reflection to do dynamic method invocation (this assumes filetype.Value is of type 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});
    }
    
    0 讨论(0)
  • 2021-02-09 13:32

    You can do it with some preparation using delegates, like this:

    private static readonly IDictionary<string,Action<string>> actionByType =
        new Dictionary<string,Action<string>> {
            {"ReadFile", ReadFile}
        ,   {"ReadMSOfficeWordFile", ReadMSOfficeWordFile}
        ,   {"ReadMSOfficeExcelFile", ReadMSOfficeExcelFile}
        ,   {"ReadPDFFile", ReadPDFFile}
        };
    

    When it is time to call your action, do it as follows:

    actionByType[actionName](file);
    
    0 讨论(0)
  • 2021-02-09 13:37

    You could also use reflection (if you're okay with the different overhead that can bring) Check this solution

    Hope that helped

    0 讨论(0)
  • 2021-02-09 13:40

    You could keep a Dictionary of delegates, as the simplest way:

    Dictionary<string, Action<string>> fileReaders = new Dictionary<string, Action<string>>() {
        {"ReadFile", ReadFile},
        {"ReadOfficeWordFile", ReadOfficeWordFile},
        {"ReadOfficeExcelFile", ReadOfficeExcelFile},
        {"ReadPDFFile", ReadPDFFile}
    };
    

    Then call it like this:

    fileReaders[fileType.Value](file);
    

    Depending on what your methods return, you may have to change the type of the delegate (Action<string> means void something(string someparam) as a method signature, for example) as well.

    0 讨论(0)
  • 2021-02-09 13:40

    I believe what you're looking for will need some refactoring of your code.

    All of your "cases" (TextFile, MSOfficeWordFile, MSOfficeExcelFile, PdfFile) should be their own classes which implement a single interface.

    Your interface should be named something like "IReadableFile" and specify a method named "ReadFile()".

    Each class should have their own implementation of "ReadFile()"

    Example:

    public interface IReadableFile
    {
        void ReadFile();
    }
    

    public class MSOfficeWordFile : IReadableFile
    {
        public void ReadFile()
        {
            ReadMSOfficeWordFile(file);
        }
    } 
    

    foreach(IReadableFile file in files)
        file.ReadFile();
    

    Code may contain some mistakes, but I hope you get the idea.

    0 讨论(0)
提交回复
热议问题