2012-08-26 31 views
7

Trong C# có thể tạo một hàm mới khi đang bay để xác định một biến không?C# Biến = hàm mới() {};

Tôi biết rằng

string getResult() { 
    if (a) 
     return "a"; 
    return "b"; 
} 
String result = getResult(); 

là có thể, nhưng tôi đang tìm một cái gì đó giống như

String result = new string getResult() { 
    if (a) 
     return "a"; 
    return "b"; 
} 

Đây có phải là có thể? Nếu có, ai đó sẽ chứng minh?

EDIT Có thể

Chỉnh sửa: Final - Giải pháp

Đây là kết quả cuối cùng của những gì tôi barbarically bị tấn cùng

Func<string> getResult =() => 
{ 
    switch (SC.Status) 
    { 
     case ServiceControllerStatus.Running: 
      return "Running"; 
     case ServiceControllerStatus.Stopped: 
      return "Stopped"; 
     case ServiceControllerStatus.Paused: 
      return "Paused"; 
     case ServiceControllerStatus.StopPending: 
      return "Stopping"; 
     case ServiceControllerStatus.StartPending: 
      return "Starting"; 
     default: 
      return "Status Changing"; 
    } 
}; 

TrayIcon.Text = "Service Status - " + getResult(); 

Trả lời

6

Một cách để xác định một chức năng như:

Func<bool, string> getResult = (a) => { 
    if (a) 
     return "a"; 
    return "b"; 
} 

Sau đó bạn có thể gọi: string foo = getResult(true);. Là một đại biểu, nó có thể được lưu trữ/thông qua và viện dẫn khi cần thiết.

Ví dụ:

string Foo(Func<bool, string> resultGetter){ 
    return resultGetter(false); 
} 

Bạn cũng có thể close xung quanh biến trong phạm vi:

bool a = true; 

Func<string> getResult =() => { 
    if (a) 
     return "a"; 
    return "b"; 
} 

string result = getResult(); 
+0

(Nếu tôi hiểu ý định của người hỏi ...) Tôi khuyên bạn nên chống lại điều này, vì nó không phải là những gì 'Func' s thường được sử dụng cho, và sẽ gây nhầm lẫn cho người đọc trong tương lai của mã của bạn (mình bao gồm) mà quen thuộc hơn với các mẫu sử dụng 'Func' bình thường. Trừ khi nó thực sự là một trường hợp mà một 'Func' hoặc' Hành động' sẽ có ý nghĩa hơn, hoặc là nội tuyến mã, hoặc làm cho nó một phương pháp riêng biệt. –

+0

Tôi sẽ phải không đồng ý. Trong khi tôi không biết nhu cầu của OP là gì và đây là một ví dụ giả tạo, khả năng xác định và lặp lại/có điều kiện/cuối cùng thực hiện một đại biểu là cả hai mạnh mẽ và phổ biến. Nhưng đó chỉ là tôi. –

+0

Điều này sẽ không thực sự làm việc cho tôi như Tim S. nói. Tôi chỉ muốn xác định nó trong một phương pháp riêng biệt, nếu tôi đã sử dụng tuyến đường này. Mục đích thực sự duy nhất của tôi khi làm điều này là định nghĩa phong cách lười biếng tất cả trong một dòng như Actionscript, hoặc những gì tôi tin là cũng có thể có trong Javo. Khi nhận ra nó có thể khó hơn tôi ban đầu có ý định tôi tò mò làm thế nào nó có thể được thực hiện, nếu nó thực sự có thể được thực hiện. –

2

Bạn muốn sử dụng câu lệnh if inline.

string result = a ? "a" : "b"; 
+0

tôi cảm thấy như thế này sẽ làm việc, ngoại trừ tôi thực sự cố gắng để thực hiện một công tắc. Tôi đơn giản hóa nó thành một câu lệnh if trong mã của tôi vì mục đích cố gắng để được hiểu. Có lẽ có một tuyên bố chuyển đổi nội tuyến? –

+1

bạn có thể làm điều đó với một 'Từ điển'. –

+0

Một 'Từ điển' phát sinh nhiều chi phí hơn một lệnh chuyển đổi đơn giản (tương đối nói). Nói chung, bạn nên cố gắng tránh sử dụng từ điển cho logic được biết đến tại thời gian biên dịch. – MgSam

0

Không chắc chắn về phạm vi của biến a là trong ví dụ của bạn, nhưng giả định rằng nó có thể truy cập trong vòng phạm vi (như trong ví dụ của bạn):

Func<string> getResult =() => 
{ 
    return a ? "a" : "b"; 
} 
+1

'Hành động ' s không trả lại bất kỳ điều gì; ý của bạn là 'Func '? Dù sao, tôi nghĩ rằng 'var' có lẽ sẽ làm việc ... – Ryan

+0

@minitech có cập nhật cảm ơn. –

+0

@minitech, 'var' không hoạt động với lambdas. Không có đủ ngữ cảnh cho trình biên dịch để biết phải làm gì. (Lỗi trình biên dịch là "Không thể gán biểu thức lambda cho biến cục bộ được nhập ngầm") –

0

Dựa trên giải pháp bạn đã đăng, đây là cách tốt hơn để làm điều này.

Thay đổi enum ServiceControllerStatus của bạn để thêm [Mô tả] thuộc tính:

public enum ServiceControllerStatus 
{ 
    [Description("Running")] 
    Running, 
    // ... others 
} 

Thêm phương pháp khuyến nông sau trong một lớp tĩnh mới:

public static string ToDescription(this Enum value) 
{ 
    var attributes = (DescriptionAttribute[])value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false); 
    return attributes.Length > 0 ? attributes[0].Description : value.ToString(); 
} 

Bây giờ bạn chỉ có thể viết:

TrayIcon.Text = "Service Status - " SC.Status.ToDescription(); 
1

Nếu bạn thực sự muốn nội tuyến, bạn có thể tạo phương thức tiện ích mở rộng cho loại String:

static class StringExtensions { 
    public static string ExecuteFunc(
      this string str, 
      Func<string, string> func 
     ) { 
     return func(str); 
    } 
} 

Và sau đó, khi bạn muốn sử dụng nó, bạn làm như vậy như vậy:

string str = "foo"; 

string result = str.ExecuteFunc(s => { 
     switch(s){ 
      case "a": 
       return "A"; 
      default: 
       return "B"; 
     } 
    } 
); 
+0

+1 để sử dụng tiện ích. Mặc dù nó không thực sự truyền chức năng xung quanh. Nó không thể được gán một lần, nhưng phải được gán bất cứ khi nào được gọi. – liang

Các vấn đề liên quan