2015-04-18 13 views
5

Có thể nào đó các thuộc tính có thể tham chiếu lẫn nhau trong khi tạo một đối tượng động một đối tượng ẩn danh (tức là bên trong bộ khởi tạo đối tượng)? Ví dụ đơn giản của tôi dưới đây cần sử dụng lại thuộc tính Age mà không thực hiện cuộc gọi thứ hai nặng tới GetAgeFromSomewhere(). Tất nhiên nó không hoạt động. Bất kỳ đề xuất về cách thực hiện điều này?Các thuộc tính có thể bên trong một bộ khởi tạo đối tượng tham chiếu lẫn nhau không?

var profile = new { 
    Age = GetAgeFromSomewhere(id), 
    IsLegal = (Age>18) 
}; 

là một cái gì đó như thế này có thể hoặc không thể xảy ra với đối tượng năng động nặc danh, đánh máy initializers đối tượng?

+1

Gán kết quả của 'GetAgeFromSomewhere' thành biến trong câu lệnh riêng trước đó. –

+0

Điều này cũng không liên quan trực tiếp đến các loại động nhưng khởi tạo. – CSharpie

+2

@CSharpie Sử dụng kiểu khai báo tĩnh, OP có thể vừa tạo ra 'IsLegal' một thuộc tính phái sinh:' public bool IsLegal {get {return Age> 18; }} ' –

Trả lời

6

Thật không may là không thể, ngay cả với các đối tượng được nhập rõ ràng. Điều này là do cách khởi tạo đối tượng hoạt động. Ví dụ:

public class MyClass 
{ 
    public int Age = 10; 
    public bool IsLegal = Age > 18; 
} 

sản lượng lỗi biên dịch này tại "IsLegal":

Lỗi 1 Một initializer lĩnh vực không có thể tham khảo các phi trường tĩnh, phương pháp, hoặc tài sản 'MyClass.Age' ..

Trình khởi tạo trường không thể tham chiếu các trường không tĩnh khác và vì các loại ẩn danh không tạo trường tĩnh, bạn không thể sử dụng giá trị của một trường để khởi tạo trường khác. Cách duy nhất xung quanh điều này là khai báo các biến bên ngoài kiểu ẩn danh và sử dụng chúng bên trong trình khởi tạo.

int age = GetAgeFromSomewhere(id); 
var profile = new { 
    Age = age, 
    IsLegal = age > 18 
}; 
+0

Câu trả lời thông tin, tuyệt vời. Cảm ơn! – user3199179

5

Đừng làm phức tạp điều, giữ cho nó đơn giản

//Create a variable 
var age = GetAgeFromSomewhere(id); 
var profile = new { 
    Age = age, 
    IsLegal = age>18 
} 
+0

nhờ nhưng tìm kiếm một giải pháp nếu có thể mà không cần tạo một chục biến trong kịch bản thật của tôi – user3199179

+2

@ user3199179, Sau đó, tạo ra một lớp bình thường và kê khai tài sản phái sinh. – Satpal

+0

tôi hỏi về đối tượng năng động – user3199179

2

gì bạn muốn là không thể thực hiện trong vòng intializers đối tượng. Bạn không thể đọc thuộc tính của đối tượng đang được khởi tạo. (Nó không quan trọng, cho dù loại là vô danh hay không.)

Thay vào đó, Tạo một lớp

public class Profile 
{ 
    public Profile(int id) 
    { 
     Age = GetAgeFromSomewhere(id); 
    } 

    public int Age { get; private set; } 
    public int IsLegal { get { return Age > 18; } } 
} 

Hoặc nhận tuổi cách lười biếng:

public class Profile 
{ 
    private readonly int _id; 

    public Profile(int id) 
    { 
     _id = id; 
    } 

    private int? _age; 
    public int Age { 
     get { 
      if (_age == null) { 
       _age = GetAgeFromSomewhere(_id); 
      } 
      return _age.Value; 
     } 
    } 

    public int IsLegal { get { return Age > 18; } } 
} 

hoặc sử dụng Lazy<T> lớp học (bắt đầu với Framework 4.0):

public class Profile 
{ 
    public Profile(int id) 
    { 
     // C# captures the `id` in a closure. 
     _lazyAge = new Lazy<int>(
      () => GetAgeFromSomewhere(id) 
     ); 
    } 

    private Lazy<int> _lazyAge; 
    public int Age { get { return _lazyAge.Value; } } 

    public int IsLegal { get { return Age > 18; } } 
} 

Gọi nó là như thế này

var profile = new Profile(id); 
+0

Vì bạn nhắc đến từ "lười biếng" trong khối mã thứ hai của bạn, tại sao không đơn giản hóa mã của bạn sử dụng 'Lazy '? 'riêng chỉ đọc một cách lười biếng age = new Lazy (() => GetAgeFromSomewhere (_id)); tuổi int công khai {get {return age.Value; }} '. – stakx

+1

xin vui lòng đọc câu hỏi là về các đối tượng động – user3199179

+1

tôi đã thêm một tuyên bố trên initializers đối tượng và các loại vô danh, cũng như một ví dụ sử dụng của 'Lazy '. Lưu ý, C# có từ khóa 'dynamic' để khai báo các đối tượng động và sử dụng thuật ngữ này trong ngữ cảnh khác có thể gây nhầm lẫn. Ở đây, bạn đang nói về các kiểu vô danh 'new {...}'. –

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