2010-02-05 64 views
6

Tôi muốn tạo toán tử bậc ba cho một số < b < c là < b & & b < c. hoặc bất kỳ lựa chọn nào khác mà bạn có thể nghĩ về điều đó là < b> c và vân vân ... Tôi là một người hâm mộ dạng shortform của riêng tôi và tôi muốn tạo ra điều đó vì tôi đã học lập trình ở trường trung học.Tôi có thể tạo các toán tử bậc ba trong C# không?

Làm cách nào?

+0

Đây có phải là câu hỏi không? – Yuliy

+3

Làm cách nào? - Có nó là – oneat

+0

là một bình luận này :-) – Jim

Trả lời

0

Bạn đã thử tìm kiếm toán tử ternary trong google để xem có điều gì đó đã tồn tại chưa?

+0

Vâng, tìm kiếm 2 giờ (lần này) vẫn cho tôi thấy rằng a? b: c dường như là hoạt động ba bậc duy nhất. –

3

Bạn không thể làm điều đó. Bạn chỉ có thể triển khai các toán tử hiện tại và không có thứ ba. <. <. toán tử trong C#.

Bên cạnh đó, một toán tử như vậy sẽ không rõ ràng với các toán tử so sánh hiện tại. Ví dụ: biểu thức a == b == c == d có nghĩa là ((a == b) == c) == d hoặc (a == b == c) == d?

+0

Như tôi đã trình bày trong ví dụ này, nó sẽ dựa trên một sơ đồ && giản đồ để chia các biến sao cho có thể là == b && b == c && c == d. –

+1

@Scott: Bạn đang thiếu điểm. Trình biên dịch sẽ biết khi nào diễn giải một biểu thức như toán tử so sánh bậc ba và khi nào sử dụng toán tử so sánh thông thường? (Ngoài ra, vì nó là một toán tử bậc ba và không phải là toán tử bậc hai (?), Nó sẽ là (a == b && b == c) == d.) – Guffa

+0

Vâng, ý tưởng có thể mở rộng, tương tự như hàm gọi với số lượng tham số tùy ý. Nhưng nó cũng sẽ được dựa trên một thư viện mà tôi sẽ sử dụng để vượt qua các bài kiểm tra tương đương tiêu chuẩn. –

0

No. Không phải trong C#. Phần mở rộng ngôn ngữ theo cách này không có sẵn trong bất kỳ phiên bản C# nào, nhưng Luca Bolognese chỉ sử dụng trình biên dịch làm dịch vụ và một số chức năng có thể cho phép mở rộng ngôn ngữ theo cách như sau: http://microsoftpdc.com/Sessions/FT11.

0

Nếu bạn muốn làm điều đó cho các kiểu dữ liệu nguyên thủy, bạn sẽ không may mắn. C# không hỗ trợ thêm toán tử cho các toán tử đó.

Trong các kiểu dữ liệu của riêng bạn, có thể trả lại một kiểu dữ liệu đặc biệt lưu trữ kết quả trung gian và kết quả so sánh. Tuy nhiên, tôi đề nghị bạn chỉ cần gắn vào ngôn ngữ C# - nếu bạn thực sự muốn kiểu dáng nhà điều hành a < b < c, hãy chuyển sang Python.

+0

Bạn có dễ dàng tích hợp các phương thức Python vào các cuộc gọi C# funtion như một chương trình ngôn ngữ kép không? (kinh nghiệm của tôi với Python đã giúp bạn bè gỡ lỗi và nó trông giống như một ngôn ngữ kịch bản) –

+0

Python là một ngôn ngữ lập trình đầy đủ flegded, và IronPython là một thực hiện của nó chạy trên nền tảng .NET và do đó tương thích với C#. Xem http://ironpython.net/ –

+0

Tương thích - có, nhưng chúng vẫn không thể trộn lẫn được; bạn luôn luôn chỉ làm việc trong một ngôn ngữ, do đó, bằng cách sử dụng một Ondergetekende

4

Rất tiếc, bạn không thể tạo toán tử của riêng mình trong C#.

Bạn có thể sử dụng phương pháp mở rộng để cho phép một cú pháp trơn tru như

bool f = b.IsBetween(a, c); 

Hoặc, nếu bạn đã là cực kỳ thông minh, bạn có thể làm:

bool f = a.IsLessThan(b).IsLessThan(c); 

làm như vậy là khó khăn, nhưng có thể. (Gợi ý: định nghĩa một đối tượng tùy chỉnh mà IsLessThan trả về các dấu vết của nó và hiểu cách nó được kết hợp với các cá thể khác của đối tượng. Về cơ bản đây là cách LINQ-to-SQL làm việc liên quan đến việc kết hợp ở đâu, Chọn, vv)

Nhưng bạn không thể xác định cú pháp toán tử của riêng bạn trong C#.

Nếu bạn quan tâm đến ngôn ngữ nơi bạn có thể xác định toán tử của riêng mình, bạn có thể cân nhắc xem xét F #.

10

Đừng tin những kẻ thù ghét;)

Bạn thể làm điều này trong C#. Đây là một ví dụ thực hiện — Tôi dựa trên chuỗi cách mà Icon thực hiện của chúng ... nếu so sánh thành công, kết quả là tham số phù hợp, nếu không kết quả "không thành công" đặc biệt sẽ được trả về.

Cú pháp bổ sung duy nhất bạn cần sử dụng là gọi đến Chain() sau mục đầu tiên.

class Program 
{ 
    static void Main(string[] args) 
    { 
     if (2.Chain() < 3 < 4) 
     { 
      Console.WriteLine("Yay!"); 
     } 
    } 
} 

public class Chainable<T> where T : IComparable<T> 
{ 
    public Chainable(T value) 
    { 
     Value = value; 
     Failed = false; 
    } 

    public Chainable() 
    { 
     Failed = true; 
    } 

    public readonly T Value; 
    public readonly bool Failed; 

    public static Chainable<T> Fail { get { return new Chainable<T>(); } } 

    public static Chainable<T> operator <(Chainable<T> me, T other) 
    { 
     if (me.Failed) 
      return Fail; 

     return me.Value.CompareTo(other) == -1 
        ? new Chainable<T>(other) 
        : Fail; 
    } 

    public static Chainable<T> operator >(Chainable<T> me, T other) 
    { 
     if (me.Failed) 
      return Fail; 

     return me.Value.CompareTo(other) == 1 
        ? new Chainable<T>(other) 
        : Fail; 
    } 

    public static Chainable<T> operator ==(Chainable<T> me, T other) 
    { 
     if (me.Failed) 
      return Fail; 

     return me.Value.CompareTo(other) == 0 
        ? new Chainable<T>(other) 
        : Fail; 
    } 

    public static Chainable<T> operator !=(Chainable<T> me, T other) 
    { 
     if (me.Failed) 
      return Fail; 

     return me.Value.CompareTo(other) != 0 
        ? new Chainable<T>(other) 
        : Fail; 
    } 

    public static bool operator true(Chainable<T> me) 
    { 
     return !me.Failed; 
    } 

    public static bool operator false(Chainable<T> me) 
    { 
     return me.Failed; 
    } 

    public override bool Equals(object obj) 
    { 
     return Value.Equals(obj); 
    } 

    public override int GetHashCode() 
    { 
     return Value.GetHashCode(); 
    } 
} 

public static class ChainExt 
{ 
    public static Chainable<T> Chain<T>(this T value) where T : IComparable<T> 
    { 
     return new Chainable<T>(value); 
    } 
} 
+1

Đó là khá mát mẻ. Vì vậy, bạn có thể làm 'if (1.Chain()

+0

Upvoted. Nhưng hãy nhớ rằng ưu tiên '<' cao hơn '==', ví dụ. Vì vậy, 'a.Chain() == b

+0

đẹp - ra giải pháp hộp, thích nó ... – Jim

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