2009-11-23 33 views
5

Chức năng của tôi trả về một số giá trị dài có chứa hai giá trị trong 32 bit thấp hơn và cao hơn.Tại sao tôi không thể lấy được từ lâu?

Tôi nghĩ cách tốt nhất để xử lý giá trị trả lại là lấy được loại tùy chỉnh của tôi từ lâu và cung cấp các bộ mở rộng loại như GetLowerValue(), GetHigherValue().

Vấn đề là .NET không cho phép để lấy được từ lâu

Nếu bạn biên dịch rằng

public class SubmitOrderResult : long 
{ 
} 

bạn nhận được:

cannot derive from sealed type 'long' 

Tại sao mà thiết kế sao và làm thế nào có thể vượt qua nó?

Cảm ơn

Trả lời

10

Như đã đề cập các loại giá trị trong .NET được niêm phong để không có cách nào bạn có thể lấy được từ lâu. Bạn nên tạo các phương thức mở rộng như được gợi ý.

Ví dụ

public static class LongExtensions 
{ 
    public static long GetLowerValue(this long value) 
    { 
     ... 
    } 

    public static long GetHigherValue(this long value) 
    { 
     ... 
    } 
} 
6

Bạn không thể lấy được từ bất kỳ Loại giá trị .NET nào - tất cả đều được niêm phong theo định nghĩa.

Có lẽ bạn có thể triển khai phương thức GetLowerValue và GetHigherValue làm phương pháp mở rộng?

+1

Phương pháp mở rộng +1 chắc chắn là cách để đi trong trường hợp này. – James

+0

Phải. Vì vậy, tôi sẽ đi cho phần mở rộng. Những gì tôi không thích về phần mở rộng là tôi sẽ mở rộng một loại dài phổ biến mà có thể không nhất thiết phải là "của tôi" dài và không chứa hai giá trị trong đó. Tạo ra một loại mới sẽ an toàn hơn. –

+0

@ James: Tôi bằng cách nào đó nghi ngờ rằng ... một loại khác biệt có vẻ thích hợp hơn nhiều. –

1

Bạn không thể vượt qua nó.

long là loại được niêm phong và do đó bạn không thể kế thừa từ chúng. Xem MSDN

Vì cấu trúc được niêm phong hoàn toàn, chúng không thể được kế thừa.

Để biết thêm thông tin, hãy xem Inheritance (C# Programming Guide).

3

Nếu tôi hiểu chính xác, chức năng của bạn thực sự trả về hai giá trị và thực tế bạn đóng gói chúng thành long là chi tiết triển khai. Trong trường hợp đó, ẩn chi tiết này và tạo ra một lớp, trong đó có giá trị và các hoạt động cần thiết:

public class SubmitOrderResult 
{ 
    private readonly long value_; 

    public int OneValue 
    { 
     get { return (int)(value_ >> 32); } 
    } 

    public int TheOtherValue 
    { 
     get { return (int)(value_ & 0xFFFFFFFF); } 
    } 

    public SubmitOrderResult(long value) 
    { value_ = value; } 
} 
+0

Tại sao nên sử dụng 'long' để lưu trữ? Tôi không nhìn thấy lợi thế ... trừ khi cho interop với P/Invoke (hoặc kịch bản tương tự, nơi truy cập cấp thấp có ý nghĩa). –

+2

Tôi hoàn toàn đồng ý và tôi đã sử dụng 'long' vì đó là yêu cầu của OP. Điểm tôi đang cố gắng thực hiện là liệu OP có chọn sử dụng 'long' trong chức năng của anh ta hay không là một chi tiết thực hiện và khách hàng không cần phải biết về điều đó. –

5

chức năng của tôi trả về một số giá trị lâu, trong đó có hai giá trị trong thấp hơn và cao hơn 32 bit.

Điều đó nghe có vẻ như thực sự, thực sự rất bẩn. Nó có thể thích hợp cho các ngôn ngữ cận kim loại (ví dụ C) nhưng không phù hợp với ngôn ngữ hướng đối tượng cao cấp hơn.

Trong ngôn ngữ OO, bạn mở rộng hệ thống kiểu, không quấy rối các loại hiện có để thực hiện đặt giá thầu của mình. Vì vậy, giải pháp nên là tạo ra một loại mới mang thông tin của bạn.

+0

Đoán của tôi là nó không thực sự là chức năng của anh ta, bởi vì sau đó anh ta sẽ không có vấn đề này. Có lẽ đó là một extern, hoặc ít nhất là một số thư viện lớp học ngoài tầm kiểm soát của mình. –

4

Điều bạn có thể làm là viết cấu trúc với toán tử chuyển đổi ẩn.Điều đó sẽ làm việc chính xác theo cách bạn muốn:

public struct SubmitOrderResult 
{ 
    private long _result; 

    public SubmitOrderResult(long result) 
    { 
     _result = result; 
    } 

    public long Result 
    { 
     get { return _result; } 
     set { _result = value; } 
    } 

    public int GetHigherValue() 
    { 
     return (int)(_result >> 32); 
    } 

    public int GetLowerValue() 
    { 
     return (int)_result; 
    } 

    public static implicit operator SubmitOrderResult(long result) 
    { 
     return new SubmitOrderResult(result); 
    } 

    public static implicit operator long(SubmitOrderResult result) 
    { 
     return result._result; 
    } 
} 

Sau đó, bạn có thể làm:

SubmitOrderResult result = someObject.TheMethod(); 
Console.WriteLine(result.GetHigherValue()); 
Console.WriteLine(result.GetLowerValue()); 

... giống như bạn muốn.

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