2009-07-27 38 views
10

Tôi có một số mã VERY không hiệu quả trong đó nhiều dòng xuất hiện 4 lần khi tôi đi qua hoán vị với các hoạt động "<" và ">" và nhiều biến và hằng số. Dường như có một cách để viết hàm một lần và truyền vào các toán tử cùng với các giá trị thay đổi nhất định và các biến "ref". Tôi phải học kỹ thuật gì? "Đại biểu" đã được đề xuất nhưng tôi không thấy cách sử dụng chúng theo cách này. Đây là trong C# 2.0, VS2005, nhưng nếu kỹ thuật này là chung chung và có thể được sử dụng với C + + quá, đó sẽ là tuyệt vời.Truyền một toán tử cùng với các tham số khác

Yêu cầu cho một số mã: Sau đây xuất hiện trong nhiều phương sách lường, với "<" và ">" dấu hiệu khác nhau cũng như một kết hợp của "+" và "-" dấu hiệu:

if (move[check].Ypos - move[check].height/200.0D < LayoutManager.VISIO_HEIGHT - lcac_c.top) 
{ 
    move[check].Ypos = move[check].Ypos + adjust; 
. 
. 
. 
+2

Bạn có thể đăng một số mã? –

+0

Ai đó có thể định dạng mã đó không? Ngoài ra, bạn có thể cho chúng tôi thêm một chút mã không? Bây giờ rất khó để xem tất cả những gì sẽ thay đổi - Nó sẽ luôn luôn chống lại 'di chuyển [kiểm tra]', và 'điều chỉnh' đến từ đâu? Dự đoán hiện tại của bạn ở chữ ký phương thức có thể hữu ích. –

+0

Nhờ Rob để làm sạch khả năng hiển thị mã của tôi! "điều chỉnh" là biến lớp và tôi thay đổi tùy thuộc vào độ phân giải màn hình và máy tính mà tôi đang giới thiệu chương trình. di chuyển là một loạt các trường hợp của một lớp Trong 2 trong số 4 biến thể của mã, tôi sẽ cho chúng tôi Xpos, chứ không phải YPos. Ngoài ra 2 trong số 4 có <, 2 have >. Bất cứ điều gì với> sẽ sử dụng dấu + trước biến điều chỉnh và ngược lại. Ngoài ra, một trong những sử dụng lcac_c.top, một trong những sử dụng lcac_c.right, vv Tôi muốn tất cả những điều này được thông qua. – user32848

Trả lời

11

Trong C++, sử dụng std::lessstd::greater functors. Cả hai phương pháp này kế thừa std::binary_function, do đó, hàm chung của bạn sẽ chấp nhận các trường hợp thuộc loại này.

Trong .NET, tương đương với std::binary_functionFunc<T, U, R>. Không có tương đương với std::lessstd::greater, nhưng nó khá tầm thường để tạo chúng. Xem ví dụ sau.

static class Functor 
{ 
    static Func<T, T, bool> Greater<T>() 
     where T : IComparable<T> 
    { 
     return delegate(T lhs, T rhs) { return lhs.CompareTo(rhs) > 0; }; 
    } 

    static Func<T, T, bool> Less<T>() 
     where T : IComparable<T> 
    { 
     return delegate(T lhs, T rhs) { return lhs.CompareTo(rhs) < 0; }; 
    } 
} 

Lưu ý, các mã trên sử dụng lớp Func<> từ NET 3.5. Nếu điều này không được chấp nhận, hãy xem xét việc xác định bạn là người được ủy quyền.

C++ gọi Ví dụ:

void DoWork(const std::binary_function<int, int, bool>& myOperator, 
      int arg1, int arg2) 
{ 
    if (myOperator(arg1, arg2)) { /* perform rest of work */ } 
} 

void main() 
{ 
    DoWork(std::less<int>(), 100, 200); 
    DoWork(std::greater<int>(), 100, 200); 
} 

C# gọi Ví dụ:

void DoWork(Func<int, int, bool> myOperator, int arg1, int arg2) 
{ 
    if (myOperator(arg1, arg2)) { /* perform rest of work */ } 
} 

void main() 
{ 
    DoWork(Functor.Less<int>(), 100, 200); 
    DoWork(Functor.Greater<int>(), 100, 200); 
} 

EDIT: Tôi sửa lại ví dụ của lớp functor như áp dụng < hoặc> khai thác một kiểu generic doesn' t làm việc (theo cách tương tự như với các mẫu C++).

+1

Đây là một câu trả lời tốt hơn nhiều so với tôi. –

+0

Trong ví dụ trên C#, Functor có sẵn trong .Net 2.0? Tôi không thể làm cho mã trên hoạt động? Tôi có cần thêm tham chiếu không? – user32848

+0

Không, Functor không phải là lớp .NET chuẩn - bạn cần tự viết nó. Ngoài ra, .NET 2.0 không chứa Func <> (nó nằm trong System.Core.dll trong .NET 3.5), vì vậy bạn sẽ cần phải sử dụng System.Predicate ở vị trí của nó. –

2

Trong C# sử dụng các đại biểu để chuyển hoạt động "<" và ">" tới mã đang thực hiện công việc.

C# Ví dụ:

public delegate bool BooleanOperatorDelegate(int a, int b) 

class OperatorsImplementer { 
    public bool OperatorLess(int a, int b) { 
     return a < b; 
    } 
} 

class AnotherOperatorsImplementer { 
    public bool OperatorLess(int a, int b) { 
     return (a + 1) < (b - 1); 
    } 
} 

class OperatorUser { 
    int DoSomethingObscene(int a, int b, BooleanOperatorDelegate operator) { 
     if (operator(a, b)) { 
      return 5; 
     } 
     else { 
      return -5; 
     } 
    } 
} 

Bạn cũng nên kiểm tra xem các đại biểu bạn nhận được như một paramater không phải là NULL.

Đây là phương pháp C để làm như vậy:

bool (*operator_func)(float a, float b) 
+0

Thành ngữ C++ thực sự sẽ sử dụng các đối tượng hàm và không phải con trỏ hàm (cụ thể, điều này sẽ cho phép sử dụng 'std: less' và các hàm tử cổ phiếu khác). –

0

Bạn có thể chuyển các toán tử bằng cách định nghĩa chúng theo cách tương tự với Toán tử Enum trong lớp Comparer này; và sau đó gọi hàm như thế này:

if (IsTrue(var1, Operator.GreaterThanOrEqual, var2)) 
    Console.WriteLine("var1 is greater than var2"); 
else 
    Console 
     .WriteLine("Unfortunately var1 is not greater than or equal var2. Sorry about that."); 

 public static class Comparer 
{ 
    public static bool IsTrue<T, U>(T value1, Operator comparisonOperator, U value2) 
       where T : U 
       where U : IComparable 
    { 
     switch (comparisonOperator) 
     { 
      case Operator.GreaterThan: 
       return value1.CompareTo(value2) > 0; 
      case Operator.GreaterThanOrEqual: 
       return value1.CompareTo(value2) >= 0; 
      case Operator.LessThan: 
       return value1.CompareTo(value2) < 0; 
      case Operator.LessThanOrEqual: 
       return value1.CompareTo(value2) <= 0; 
      case Operator.Equal: 
       return value1.CompareTo(value2) == 0; 
      default: 
       return false; 
     } 
    } 

    public enum Operator 
    { 
     GreaterThan = 1, 
     GreaterThanOrEqual = 2, 
     LessThan = 3, 
     LessThanOrEqual = 4, 
     Equal = 5 
    } 
} 
+0

Vui lòng xem xét thêm một số chi tiết và giải thích để hỗ trợ câu trả lời của bạn để giúp đỡ người khác –

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