2012-04-06 40 views
11

Tôi cần tham số của thuộc tính thay đổi trong thời gian chạy. Tôi đã đơn giản hóa vấn đề của mình thành ví dụ đơn giản.Thay đổi thông số của thuộc tính tùy chỉnh tại thời gian chạy

Thuộc tính lớp:

[AttributeUsage(AttributeTargets.Property)] 
    public class MyAttribute : Attribute 
    { 
     public string Name { get; set; } 
    } 

Simple thực thể Mà đã trang trí thuộc tính với các thuộc tính:

public class MyEntity 
    { 
     [MyAttribute(Name="OldValue1")] 
     public string Data1{ get; set; } 

     [MyAttribute(Name = "OldValue2")] 
     public string Data2 { get; set; } 
    } 

Tôi tạo ra instace của lớp MyEntity. Tôi có thể thay đổi giá trị của các thuộc tính của đối tượng, nhưng tôi không thể thay đổi giá trị của tên thuộc tính của thuộc tính trên thực thể đối tượng. Có thể không?

Giá trị của tài sản trên thực thể đối tượng tôi có thể thay đổi với phần mã này:

   entityProp.SetValue(entity,"NewData",null); 

nhưng tôi không thay đổi giá trị như thế nào của thuộc tính Tên tài sản trên đối tượng thực thể

này không hoạt động:

attProp.SetValue(attribute,"NewData",null); 

Giá trị Tên propery vẫn còn nguyên bản.

Đây là tất cả mã kiểm tra. Cảm ơn bạn vì hellp.

[TestMethod] 
    public void Test() 
    { 
     var entity = new MyEntity 
         { 
          Data1 = "OldData", 
          Data2 = "OldData" 
         }; 

     PropertyInfo[] entityProps = entity.GetType().GetProperties(); 

     foreach (var entityProp in entityProps) 
     { 
      var attribute = Attribute.GetCustomAttribute(entityProp, typeof (MyAttribute)) as MyAttribute; 

      if (attribute != null) 
      { 
       //get attribute’s property NAME 
       PropertyInfo attProp= attribute.GetType().GetProperty("Name"); 

       //get entity property value 
       var propertyValue = entityProp.GetValue(entity, null); 

       //get attribute’s property NAME value 
       var atributeNameValue = attProp.GetValue(entity, null); 

       TestContext.WriteLine(string.Format("property name:{0} property value: {1} : atribute name value: {2}\n", 
        entityProp.Name, propertyValue, atributeNameValue)); 

       //change values 
       entityProp.SetValue(entity,"NewData",null); 

       //how can I change value of property Name on object entity ? 
       attProp.SetValue(attribute,"NewData",null); 

      } 

     } 

     TestContext.WriteLine(string.Format("After change\n")); 

     foreach (var entityProp in entityProps) 
     { 
      var attribute = Attribute.GetCustomAttribute(entityProp, typeof(MyAttribute)) as MyAttribute; 

      if (attribute != null) 
      { 

       PropertyInfo attProp = attribute.GetType().GetProperty("Name"); 

       var propertyValue = entityProp.GetValue(entity, null); 
       var atributeNameValue = attProp.GetValue(entity, null); 

       TestContext.WriteLine(string.Format("property name:{0} property value: {1} : atribute name value: {2}\n", 
        entityProp.Name, propertyValue, atributeNameValue)); 
      } 
     } 



    } 

CHỈNH SỬA: Tôi xóa bài gốc và thêm mẫu rất đơn giản. Xin lỗi

+0

Lưu ý phụ: tại sao phương pháp thứ hai của bạn lại bắt và sau đó ném ngoại lệ? –

Trả lời

10

Bạn không thể thay đổi thuộc tính khi chạy. Chúng được nhúng vào siêu dữ liệu của hội đồng. Phương thức của bạn đang thay đổi trạng thái bên trong của một cá thể cụ thể; nhưng khi bạn nạp lại thuộc tính, bạn sẽ nhận được một cá thể khác.

+0

@ Giống như tôi đã đặt rất nhiều nỗ lực vào việc tìm kiếm một giải pháp để thay đổi các thuộc tính trong thời gian chạy. Ngay cả với 1337 kỹ năng haxxor của tôi, tôi không tìm thấy gì cả. Bạn có thể không thích câu trả lời này, nhưng tiếc là nó là chính xác. – payo

+0

Bạn đúng Tôi đã dành một ngày nhưng không thể tìm thấy giải pháp vì vấn đề này không có giải pháp. :(vì vậy thuộc tính khu vực chỉ đọc? – Mike

3

Điều này là không thể với sự phản ánh, như (như đã lưu ý) siêu dữ liệu được cố định. Tuy nhiên, một phần có thể với TypeDescriptor, cho phép thêm và thay thế các thuộc tính trong thời gian chạy, và cung cấp các mô hình thay thế hoàn chỉnh (TypeDescriptionProvider, v.v.). Cách tiếp cận này sẽ không được tôn trọng bởi bất kỳ mã nào sử dụng sự phản chiếu, nhưng bất kỳ mã nào sử dụng TypeDescriptor (thông thường nhất, ràng buộc dữ liệu và mã giao diện người dùng khác) sẽ nhận thấy những thay đổi.

Lưu ý TypeDescriptor chỉ thực sự hoạt động với một trong mỗi loại thuộc tính cho mỗi kiểu/thành viên; các thuộc tính đa cá thể không được hỗ trợ tốt.

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