Trong .NET, một loại giá trị (C # struct
) không thể có hàm tạo không có tham số. Theo bài đăng này, điều này được ủy quyền bởi đặc tả CLI. Điều gì xảy ra là với mỗi loại giá trị, một hàm tạo mặc định được tạo (bởi trình biên dịch?) Đã khởi tạo tất cả các thành viên về 0 (hoặc null
).
Tại sao nó không được phép định nghĩa một hàm tạo mặc định như vậy?
Một cách sử dụng tầm thường là cho các số hữu tỷ:
public struct Rational {
private long numerator;
private long denominator;
public Rational(long num, long denom)
{ /* Todo: Find GCD etc. */ }
public Rational(long num)
{
numerator = num;
denominator = 1;
}
public Rational() // This is not allowed
{
numerator = 0;
denominator = 1;
}
}
Sử dụng phiên bản hiện tại của C #, một Rational mặc định là 0/0
không thú vị lắm.
PS : Các tham số mặc định sẽ giúp giải quyết điều này cho C # 4.0 hay hàm tạo mặc định do CLR xác định sẽ được gọi?
Jon Skeet trả lời:
Để sử dụng ví dụ của bạn, điều bạn muốn xảy ra khi ai đó đã làm:
Rational[] fractions = new Rational[1000];
Nó có nên chạy qua constructor của bạn 1000 lần không?
Chắc chắn nó nên, đó là lý do tại sao tôi đã viết hàm tạo mặc định ở vị trí đầu tiên. CLR nên sử dụng hàm tạo zeroing mặc định khi không có hàm tạo mặc định rõ ràng nào được xác định; theo cách đó bạn chỉ trả tiền cho những gì bạn sử dụng. Sau đó, nếu tôi muốn một thùng chứa 1000 Rational
s không mặc định (và muốn tối ưu hóa 1000 công trình), tôi sẽ sử dụng một List<Rational>
thay vì một mảng.
Lý do này, trong tâm trí của tôi, không đủ mạnh để ngăn chặn định nghĩa của một nhà xây dựng mặc định.
Rational()
gọi ctor không tham số thay vì Rational(long num=0, long denom=1)
.
new Rational()
sẽ gọi hàm tạo nếu nó tồn tại, tuy nhiên nếu nó không tồn tại, new Rational()
sẽ tương đương với default(Rational)
. Trong mọi trường hợp, bạn được khuyến khích sử dụng cú pháp default(Rational)
khi bạn muốn "giá trị 0" của cấu trúc của bạn (đó là một số "xấu" với thiết kế được đề xuất của bạn Rational
). Giá trị mặc định cho một loại giá trị T
luôn luôn default(T)
. Vì vậy, new Rational[1000]
sẽ không bao giờ gọi các nhà xây dựng cấu trúc.
denominator - 1
bên trong cấu trúc, để giá trị mặc định trở thành 0/1
Then if I want a container of 1000 non-default Rationals (and want to optimize away the 1000 constructions) I will use a List<Rational> rather than an array.
Tại sao bạn lại mong đợi một mảng sẽ gọi một hàm tạo khác đến một Danh sách cho một cấu trúc?