2015-05-20 19 views
7

xem xét mã này:Đảm bảo Khởi tạo biến C#

public string Variable1 { get; set;} 
public int Variable2 { get; set;} 

public void Function() 
{ 
// Has been Variable1 Initialized? 
} 

Bên trong chức năng, tôi muốn biết nếu một giá trị đã được gửi đến Variable1 & Variable2, trước khi gọi hàm,

ngay cả khi các giá trị dEFAULT đã được gửi đi, đó là ok (null cho chuỗi & 0 cho int)

+4

Tôi nghĩ câu trả lời meta ở đây là "vì vậy đừng làm điều đó". Đảm bảo tất cả các biến được khởi tạo trong hàm tạo. – Martijn

+0

Điều gì sẽ xảy ra nếu tôi có hai chức năng. F1 & F2, mỗi lần sử dụng cả hai Biến. Nhưng đối với F1 tôi phải chắc chắn rằng người gọi hàm đã đặt giá trị cho các biến, ngay cả khi các biến đó là null.Đối với F2 tôi không quan tâm, tôi không muốn ép anh ta gửi thứ gì đó trong nhà xây dựng! –

+0

nếu cho F1 bạn cần * người gọi * để thiết lập các biến, tại sao bạn không vượt qua chúng như là đối số cho F1? – Martijn

Trả lời

8

Xem xét sử dụng một wrapper đơn giản như thế này:

public struct AssignableProperty<T> 
{ 
    private T _value; 

    public T Value 
    { 
     get { return _value; } 
     set 
     { 
      WasAssigned = true; 
      _value = value; 
     } 
    } 

    public bool WasAssigned { get; private set; } 

    public static implicit operator AssignableProperty<T>(T data) 
    { 
     return new AssignableProperty<T>() { Value = data }; 
    } 

    public static bool operator ==(AssignableProperty<T> initial, T data) 
    { 
     return initial.Value.Equals(data); 
    } 

    public static bool operator !=(AssignableProperty<T> initial, T data) 
    { 
     return !initial.Value.Equals(data); 
    } 

    public override string ToString() 
    { 
     return Value.ToString(); 
    } 
} 

Sau đó nhìn class'll của bạn như thế này:

public class Test 
{ 
    public AssignableProperty<string> Variable1 { get; set; } 
    public AssignableProperty<int> Variable2 { get; set; } 

    public void Function() 
    { 
     if(Variable1.WasAssigned&&Variable2.WasAssigned) 
      //do stuff 
    } 
} 

Bạn có thể đi xa hơn và thêm ném ngoại lệ hoặc hợp đồng getter, vì vậy nếu ai đó sẽ cố truy cập vào giá trị chưa được khởi tạo, nó sẽ ném một ngoại lệ hoặc cho bạn thấy cảnh báo

+0

Nhược điểm với cách tiếp cận này là bây giờ bạn phải nói 'instance.Variable1.Value =" something "' để thiết lập thuộc tính. – Sean

+0

@Sean Bạn nói đúng, có thể giúp bạn tiết kiệm được sự tự nhiên và lặp lại ở mọi nơi bạn muốn có một lá cờ. –

+1

@Sean nope, AFAIK bạn có thể ghi đè lên các phép toán diễn viên và so sánh để bạn có thể thực hiện một phép gán đơn giản như Variable1 = "something" và so sánh với kiểu ban đầu (T) sẽ không bị đau. Những gì bạn thực sự thiếu là bộ nhớ –

2

Một số vấn đề cơ bản về giá trị mặc định trong C#:

Khi một thể hiện của một lớp (hoặc cấu trúc) được tạo, tất cả các trường được khởi tạo với giá trị mặc định tương ứng của chúng.

Đối với các loại tham chiếu, nó sẽ là null. Đối với các loại giá trị, nó sẽ tương đương với 0. Điều này dễ dàng giải thích vì việc quản lý bộ nhớ đảm bảo rằng bộ nhớ được cấp phát mới được khởi tạo thành 0x0 byte.

Thuộc tính tự động ẩn trường được tạo nhưng có một trường. Vì vậy, các quy tắc tương tự áp dụng.

Bây giờ để trả lời câu hỏi của bạn, cách tốt nhất để đảm bảo rằng giá trị này được khởi tạo là làm cho một nhà xây dựng với một tham số cho từng lĩnh vực/tài sản và che giấu các nhà xây dựng mặc định không có tham số:

public Yourtype(String param1, Int32 param2) 
{ 
    this.Variable1 = param1; 
    this.Variable2 = param2; 
} 

private Yourtype() { } 

Các lựa chọn thay thế khác được mô tả trong câu trả lời @Sean và @Alex nếu chỉ có một tập hợp con các thuộc tính/trường cần được khởi tạo/kiểm tra. Nhưng điều này ẩn một số chi phí (một bool cho mỗi thuộc tính/trường và một số hướng dẫn).

-2

Bạn chỉ cần kiểm tra cả hai biến để xem liệu chúng có giá trị nào được gán cho chúng trong chức năng của bạn

public void Function() 
{ 

    if (String.IsNullOrEmpty(Variable1) && Variable2 ==0) 
    { 
     // Variables are not assigned 
    } 

} 
+1

Và nếu 'Biến1' là' null', điều đó có nghĩa là ai đó đã khởi tạo giá trị hay không? –

+0

Nếu bạn muốn kiểm tra giá trị mặc định của Loại khi chạy, bạn nên sử dụng: http://stackoverflow.com/questions/1281161/how-to-get-the-default-value-of-a-type-if loại-kiểu-chỉ-được-biết-như-hệ-thống- –

+0

Tôi không muốn kiểm tra giá trị mặc định. Tôi muốn kiểm tra nếu trước khi gọi hàm, ai đó đã gửi một cái gì đó đến var, ngay cả khi đó là NULL hoặc số không hoặc bất kỳ giá trị mặc định cho mỗi loại. –

0

Đối với các loại tài liệu tham khảo bạn sẽ cần phải thêm một lá cờ:

string m_Variable1; 
bool m_IsVariable1Set; 

public string Variable1 
{ 
    get{return m_Variable1;} 
    set{m_IsVariable1Set = true; m_Variable1 = value;} 
} 

Đối với các loại giá trị mà bạn có thể sử dụng một giá trị nullable

int? m_Variable2; 

int Variable2 
{ 
    get{return m_Variable2.GetValueOrDefault();} 
    set{m_Variable2 = value;} 
} 

Mà bạn sau đó có thể kiểm tra xem nó có được đặt bằng cách sử dụng m_Variable2.HasValue hay không.

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