Tất nhiên, bạn có thể đi bộ biểu thức-cây và sau đó sử dụng Delegate.CreateDelegate
để tạo Action<,>
thích hợp. Nó khá đơn giản, ngoại trừ tất cả các kiểm tra xác nhận hợp lệ (tôi không chắc chắn nếu tôi đã bao trả mọi thứ):
Tôi không có chuyên gia về biểu thức, nhưng tôi không nghĩ rằng xây dựng một biểu thức -tree và sau đó gọi Compile
là có thể ở đây vì cây biểu thức không thể chứa các câu lệnh gán, theo như tôi biết. (EDIT: Rõ ràng, chúng đã được thêm vào trong .NET 4. Đó là một tính năng khó tìm thấy vì trình biên dịch C# dường như không thể xây dựng chúng từ lambdas).
public static Action<TContaining, TProperty>
CreateSetter<TContaining, TProperty>
(Expression<Func<TContaining, TProperty>> getter)
{
if (getter == null)
throw new ArgumentNullException("getter");
var memberEx = getter.Body as MemberExpression;
if (memberEx == null)
throw new ArgumentException("Body is not a member-expression.");
var property = memberEx.Member as PropertyInfo;
if (property == null)
throw new ArgumentException("Member is not a property.");
if(!property.CanWrite)
throw new ArgumentException("Property is not writable.");
return (Action<TContaining, TProperty>)
Delegate.CreateDelegate(typeof(Action<TContaining, TProperty>),
property.GetSetMethod());
}
Cách sử dụng:
public class Person { public int Age { get; set; } }
...
static void Main(string[] args)
{
var setter = CreateSetter((Person p) => p.Age);
var person = new Person();
setter(person, 25);
Console.WriteLine(person.Age); // 25
}
Do lưu ý rằng điều này tạo ra một thể hiện ủy nhiệm mở, có nghĩa là nó không bị ràng buộc vào bất kỳ trường hợp cụ thể của TContaining
. Thật đơn giản để sửa đổi nó để được ràng buộc với một cá thể cụ thể cụ thể; bạn cũng sẽ phải vượt qua một phương thức TContaining
và sau đó sử dụng quá tải khác nhau của Delegate.CreateDelegate
. Chữ ký của phương thức sẽ trông giống như sau:
public static Action<TProperty> CreateSetter<TContaining, TProperty>
(Expression<Func<TContaining, TProperty>> getter, TContaining obj)
Bạn không có nghĩa là 'Hành động'? Ngoài ra, chúng ta cũng có thể làm cho 'int' một tham số kiểu. –
Ani
Ani, vâng bạn nói đúng - Ý tôi là Action và tất nhiên int cũng là một tham số chung. –
Alex