Nó có thể được thực hiện, nhưng làm điều đó đúng sẽ là khá khó khăn (và nó chắc chắn sẽ không phù hợp trong câu trả lời của tôi). Việc thực hiện đơn giản sau đây giả định rằng đối tượng của bạn đã chỉ tài sản và tham số-less constructor đọc-viết:
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
này hơi đánh bại điểm, bởi vì có thể bạn sẽ muốn sử dụng này trên các loại không thay đổi - nhưng sau đó bạn luôn luôn có để gọi hàm tạo với tất cả các đối số và không rõ ràng cách liên kết các tham số hàm tạo (khi bạn tạo một cá thể) với các thuộc tính mà bạn có thể đọc.
Phương pháp With
tạo ra một trường hợp mới, bản sao tất cả các giá trị tài sản và sau đó thiết lập một mà bạn muốn thay đổi (bằng cách sử dụng PropertyInfo
chiết xuất từ cây biểu hiện - mà không cần bất kỳ kiểm tra)
public static T With<T, P>(this T self, Expression<Func<T, P>> selector, P newValue)
{
var me = (MemberExpression)selector.Body;
var changedProp = (System.Reflection.PropertyInfo)me.Member;
var clone = Activator.CreateInstance<T>();
foreach (var prop in typeof(T).GetProperties())
prop.SetValue(clone, prop.GetValue(self));
changedProp.SetValue(clone, newValue);
return clone;
}
Sau đây bản demo cư xử như mong đợi, nhưng như tôi đã nói, nó có rất nhiều hạn chế:
var person = new Person() { Name = "Tomas", Age = 1 };
var newPerson = person.With(p => p.Age, 20);
nói chung, tôi nghĩ rằng sử dụng một phương pháp phản ánh dựa trên phổ quát như With
đây có thể không phải su một ý tưởng hay, trừ khi bạn có nhiều thời gian để thực hiện nó đúng cách. Có thể dễ dàng hơn khi thực hiện một phương thức With
cho mọi loại mà bạn sử dụng có tham số tùy chọn và đặt giá trị của chúng thành giá trị nhân bản (được tạo bằng tay) nếu giá trị không phải là null
. Chữ ký sẽ là một cái gì đó như:
public Person With(string name=null, int? age=null) { ... }
Có thể điều này sẽ hữu ích: http://v2matveev.blogspot.com/2010/05/copy-and-update-in-c.html – desco
bản sao có thể có của [C#: cách xác định phương thức tiện ích mở rộng là "bằng "trong F #?] (http://stackoverflow.com/questions/6832880/c-how-to-define-an-extension-method-as-with-in-f) –