2012-03-06 41 views
7

Tôi đang sử dụng sau đây ngay bây giờ:Sử dụng biến ở vị trí của tên hàm

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

Nó hoạt động, nhưng nó cảm thấy kinda sai. Cách Python sẽ giống như thế này:

foreach string file in files: 
    filetype.Value(file) 

Tôi thực sự khó tưởng tượng rằng C# không thể làm điều gì đó như thế này. Nó có thể là kỹ năng của Google của tôi là xấu, nhưng tôi không thể hình dung nó ra.

SOLUTION

public static readonly IDictionary<string, Action<string>> FileTypesDict = new Dictionary<string,Action<string>> { 
    {"*.txt", ReadFile}, 
    {"*.doc", ReadMSOfficeWordFile}, 
    {"*.docx", ReadMSOfficeWordFile}, 
    {"*.xls", ReadMSOfficeExcelFile}, 
    {"*.xlsx", ReadMSOfficeExcelFile}, 
    {"*.pdf", ReadPDFFile}, 
}; 

 

foreach (KeyValuePair<string, Action<string>> 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); 
    } 
} 
+0

tôi xin lỗi nhưng tôi không thể tìm ra loại tệp là gì? –

+1

Cân nhắc tạo các giá trị chuyển đổi enum thay vì chuỗi. Không phải là một giải pháp cho vấn đề của bạn mà là một thực hành tốt để đảm bảo bạn nắm bắt được thời gian biên dịch lỗi. – Stilgar

+0

Hiển thị cho chúng tôi cách bạn có được/xây dựng '' fileType''s. Có thể một sự thay đổi nhỏ ở đó (cung cấp một đại biểu thay vì chuỗi) làm cho nó dễ dàng biến mất. –

Trả lời

8

Bạn có thể làm điều đó với một số chuẩn bị sử dụng các đại biểu, như thế này:

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

Khi đó là thời gian để gọi hành động của bạn , hãy thực hiện như sau:

actionByType[actionName](file); 
+0

Python có thể làm điều đó bởi vì nó là một ngôn ngữ động. Mặc dù C# có hỗ trợ cho các loại động nhưng nó không phải là một ngôn ngữ động. Đó là lý do tại sao bạn cần sử dụng một cái gì đó như thế này – linkerro

+0

Tôi thích điều này nhưng tôi thấy lỗi: Lỗi Đối số '2': không thể chuyển đổi từ 'nhóm phương pháp' thành 'System.Action ' – MTeck

+0

@MTeck Các phương thức 'XYZFile (...)' của bạn có cùng chữ ký không? Họ có lấy 'RegularExpressions.Group' không? Ngoài ra, các phương thức 'XYZFile (...)' của bạn là tĩnh? – dasblinkenlight

4

Bạn có thể giữ một Dictionary của các đại biểu, như là cách đơn giản nhất:

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

Sau đó gọi nó là như thế này:

fileReaders[fileType.Value](file); 

Tùy thuộc vào những gì các phương pháp của bạn trở lại, bạn có thể có để thay đổi loại đại biểu (ví dụ: Action<string> có nghĩa là void something(string someparam) làm chữ ký phương thức).

6

Bạn có thể sử dụng một đại biểu:

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

Bạn cũng có thể sử dụng phản chiếu (nếu bạn đang okay với overhead khác nhau mà có thể mang lại) Kiểm tra này solution

Hy vọng rằng sẽ giúp

2

Tôi tin rằng những gì bạn đang tìm kiếm sẽ cần một số tái cấu trúc mã của bạn.

Tất cả các "trường hợp" của bạn (TextFile, MSOfficeWordFile, MSOfficeExcelFile, PdfFile) phải là các lớp riêng của chúng thực hiện một giao diện duy nhất.

Giao diện của bạn phải được đặt tên là "IReadableFile" và chỉ định phương thức có tên là "ReadFile()".

Mỗi lớp nên có thực hiện riêng của họ "ReadFile()"

Ví dụ:

public interface IReadableFile 
{ 
    void ReadFile(); 
} 

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

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

Mã có thể chứa một số sai lầm, nhưng tôi hy vọng bạn có được ý tưởng.

0

Nếu bạn đang tìm kiếm một cách để tránh việc lập bản đồ rõ ràng của tên phương pháp để các giá trị chuỗi bạn có thể sử dụng phản ánh để làm phương pháp gọi động (điều này giả định filetype.Value là loại 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}); 
} 
Các vấn đề liên quan