2009-02-11 23 views
18

Có thể ẩn các nhà xây dựng parameterless từ một người dùng trong C#ẩn parameterless constructor trên struct

Tôi muốn buộc họ phải luôn luôn sử dụng các nhà xây dựng với các thông số

ví dụ lớp này Chức

public struct Position 
{ 
    private readonly int _xposn; 
    private readonly int _yposn; 

    public int Xposn 
    { 
     get { return _xposn; } 
    } 

    public int Yposn 
    { 
     get { return _yposn; } 
    } 

    public Position(int xposn, int yposn) 
    { 
     _xposn = xposn; 
     _yposn = yposn; 
    }   
} 

Tôi chỉ muốn người dùng có thể mới lên một vị trí bằng cách xác định x và y phối

Tuy nhiên, các nhà xây dựng parameterless là LUÔN availiable

Tôi không thể làm cho nó tin . Hoặc thậm chí xác định nó như nào

Tôi đã đọc Why can't I define a default constructor for a struct in .NET?

nhưng nó doesnt thực sự giúp

Nếu đây là không thể - là những cách tốt nhất để phát hiện nếu Chức Tôi được thông qua có giá trị?

Kiểm tra tính hiệu quả của từng trường thuộc tính? Có cách nào không?

cảm ơn

Trả lời

19

Không, bạn không thể thực hiện việc này. Như bạn đã nói, similar question đã được hỏi trước đó - và tôi nghĩ câu trả lời là khá rõ ràng rằng bạn không thể làm điều đó.

Bạn có thểcreate a private parameterless constructor for a struct, nhưng không phải trong C#. Tuy nhiên, ngay cả khi bạn làm điều đó nó không thực sự giúp - bởi vì bạn có thể dễ dàng làm việc xung quanh nó:

MyStruct[] tmp = new MyStruct[1]; 
MyStruct gotcha = tmp[0]; 

Đó sẽ là giá trị mặc định của MyStruct - "tất cả zero" giá trị - mà không bao giờ gọi một constructor .

Bạn có thể dễ dàng thêm phương thức Xác thực vào cấu trúc của mình và gọi mỗi khi bạn nhận được một tham số dưới dạng tham số, phải thừa nhận.

+3

Tôi thấy điều này như là một vấn đề khả năng sử dụng nhiều hơn bất cứ điều gì khác. Hàm khởi tạo mặc định có thể tạo một đối tượng _valid_, nhưng đối với nhiều cấu trúc, nó sẽ không là những gì người dùng sẽ muốn hoặc mong đợi. Tuy nhiên một số người sẽ sử dụng hàm tạo mặc định đó chỉ vì đó là tùy chọn đầu tiên mà IDE của họ cung cấp cho họ.Và sau đó họ sẽ có những lỗi gây nhầm lẫn gây ra bởi các cấu trúc zero-out cần phải được lấp đầy với dữ liệu, hoặc họ sẽ lãng phí thời gian cố gắng tìm ra lý do tại sao họ không thể thiết lập các thuộc tính trên một cấu trúc bất biến. Từ quan điểm thiết kế API, tôi muốn nó có thể ẩn hàm khởi tạo mặc định. –

+1

+1 @MB. Một hàm tạo mặc định riêng sẽ giúp, ngay cả khi một "kẻ ngốc" được xác định có thể làm việc xung quanh nó. Là một muối C++, tôi nghĩ 'riêng tư' là một gợi ý không tự bắn mình vào chân, luôn luôn có một con trỏ xung quanh bằng cách sử dụng con trỏ. Và ngữ nghĩa mảng có thể được quan tâm bằng cách không cho phép các mảng của các cấu trúc như vậy được tạo ra. –

+0

@roryapL Cố định, cảm ơn. –

2

Một cấu trúc theo nghĩa đen là tuyên bố về cách bộ nhớ sẽ hiển thị.

Ngay cả khi bạn sử dụng một đối tượng, con trỏ đối tượng được khai báo, bất kể nó có rỗng hay không.

Lý do bạn không thể ẩn hàm tạo là do cấu trúc yêu cầu CLR có thể tạo nó như bên trong nó phải làm điều này.

Bạn có thể chuyển đổi cấu trúc này thành đối tượng để thực hiện tác vụ này. Hoặc sử dụng phân tích tĩnh để đảm bảo nó được intialized trước khi bạn sử dụng nó?

struct point 
{ 
    int xpos; 
    int ypos; 
} 

Có google cho các đối tượng bất biến, đây dường như là những gì sau của bạn. Tôi tin rằng họ đang tìm cách để thêm tính năng này (nhưng không phải trong C# 4) vào ngôn ngữ chính nó, bởi vì nó là một yêu cầu chung. Có một nhu cầu cụ thể cho một cấu trúc ở đây?

+0

ý của bạn là gì? sử dụng phân tích tĩnh để đảm bảo nó được intialized bạn muốn kiểm tra từng trường có giá trị không? – ChrisCa

+0

Bạn có thể chạy công cụ phân tích tĩnh với quy tắc để đảm bảo rằng bất kỳ lúc nào ai đó sử dụng loại trong mã của họ để hai giá trị được intialized. hoặc bạn có thể làm một số bước chân ưa thích bằng cách tuyên bố nó như là một đối tượng để làm kiểm tra, và sau đó thay đổi thành một cấu trúc trong bản phát hành. – Spence

4

Không thể ẩn nó. Structs không thể xác định lại hàm tạo zero arg, do đó khả năng hiển thị của nó không thể được định nghĩa lại.

+0

Vâng, .NET cho phép bạn cung cấp một hàm tạo parameterless tùy biến - nhưng bạn không thể làm điều đó * trực tiếp * trong C# và nó cũng không giúp ích gì nhiều, vì bạn có thể dễ dàng làm việc xung quanh nó. –

1

Bạn không thể tạo cấu trúc với hàm tạo thông số riêng tư hoặc thậm chí khai báo hàm tạo ít tham số. Bạn sẽ phải thay đổi nó thành một lớp học. Structs không cho phép khai báo một constructor parameterless.

Từ Structs Tutorial trên MSDN:

Struct có thể tuyên bố nhà thầu, nhưng phải mất các thông số. Nó là một lỗi để khai báo một constructor mặc định (parameterless) cho một struct. Cấu trúc thành viên không thể có initializers. Một hàm tạo mặc định luôn được cung cấp để khởi tạo các thành viên struct thành các giá trị mặc định của chúng.

Từ C# specification trên MSDN:

11.3 Class và struct khác biệt

Struct khác với các lớp học trên nhiều phương diện:

  • Struct là kiểu giá trị (Phần 11.3.1).
  • Tất cả các loại cấu trúc thừa kế hoàn toàn từ lớp System.ValueType (Mục 11.3.2). Chuyển nhượng cho một biến số của một loại cấu trúc tạo ra một bản sao giá trị đang được gán (Mục 11.3.3).
  • Giá trị mặc định của cấu trúc là giá trị được tạo bằng cách đặt tất cả các giá trị trường loại thành giá trị mặc định và tất cả các trường loại tham chiếu thành null (Mục 11.3.4). Quyền anh và hoạt động unboxing được sử dụng để chuyển đổi giữa loại cấu trúc và đối tượng (Mục 11.3.5).
  • Ý nghĩa của việc này là khác nhau đối với các cấu trúc (Mục 11.3.6).
  • Tuyên bố trường hợp sơ thẩm cho cấu trúc không được phép bao gồm trình khởi tạo biến (Mục 11.3.7).
  • Cấu trúc không được phép khai báo một hàm tạo mẫu không tham số (Mục 11.3.8).
  • Cấu trúc không được phép khai báo một hàm hủy (Mục 11.3.9).
Các vấn đề liên quan