2010-07-11 21 views
10

Tôi có nhiều đối tượng lớn, mỗi đối tượng có khoảng 60 chuỗi. Tôi phải cắt tất cả các chuỗi đó, và tôi muốn làm như vậy mà không cần phải đi this.mystring = this.mystring.Trim(). Thay vào đó, tôi đang tìm một cách để tự động có từng đối tượng khám phá các chuỗi riêng của nó và sau đó thực hiện thao tác.Lặp lại qua các Chuỗi & Cắt riêng của Đối tượng mỗi

Tôi biết một chút về sự phản chiếu, nhưng không đủ, nhưng tôi nghĩ điều này là có thể?

Ngoài ra, tôi không chắc chắn nếu điều này quan trọng, nhưng một số thuộc tính chuỗi là chỉ đọc (chỉ có một getter), vì vậy những tài sản sẽ phải được bỏ qua.

Trợ giúp?

Trả lời

14

Vâng, thật dễ dàng để có được tất cả các thuộc tính và tìm ra những thuộc tính nào là chuỗi và có thể ghi. LINQ làm cho nó dễ dàng hơn.

var props = instance.GetType() 
        .GetProperties(BindingFlags.Instance | BindingFlags.Public) 
        // Ignore non-string properties 
        .Where(prop => prop.PropertyType == typeof(string)) 
        // Ignore indexers 
        .Where(prop => prop.GetIndexParameters().Length == 0) 
        // Must be both readable and writable 
        .Where(prop => prop.CanWrite && prop.CanRead); 

foreach (PropertyInfo prop in props) 
{ 
    string value = (string) prop.GetValue(instance, null); 
    if (value != null) 
    { 
     value = value.Trim(); 
     prop.SetValue(instance, value, null); 
    } 
} 

Bạn có thể muốn chỉ thiết lập thuộc tính nếu cắt tỉa thực sự làm cho một sự khác biệt, để tránh tính toán dự phòng cho tài sản phức tạp - hoặc nó có thể không phải là một vấn đề cho bạn.

Có nhiều cách khác nhau để cải thiện hiệu suất nếu cần thiết - những thứ như:

  • Đơn giản chỉ cần bộ nhớ đệm các thuộc tính có liên quan đối với từng loại
  • Sử dụng Delegate.CreateDelegate để xây dựng các đại biểu cho getter và setter
  • Có thể sử dụng biểu hiện cây, mặc dù tôi không chắc liệu họ có giúp được ở đây không

Tôi sẽ không thực hiện bất kỳ bước nào trong số những bước đó trừ khi thực hiện e thực sự là một vấn đề.

+0

Tôi nghĩ cây bất động sản được tự động lưu vào bộ nhớ cache nếu không ở chế độ gỡ lỗi? Tôi đã đọc một vài lần. Điều này có đúng không? – Alex

+1

Trong trường hợp này, 'Expression' sẽ là một nỗi đau, ngay cả trong 4.0; Tuy nhiên, việc kết hợp nhiều 'Action ' vào một đại biểu duy nhất sẽ hoạt động tốt. –

+0

@Alex - biểu thức lambda trong * nguồn * có thể thực hiện một số điều thông minh bằng cách sử dụng trường đại biểu sao lưu. Tuy nhiên, AFAIK không đúng với các cây được xây dựng bằng tay và được biên dịch ('Biên dịch') khi chạy. –

3

Cái gì như:

foreach (PropertyInfo prop in obj.GetType().GetProperties(
     BindingFlags.Instance | BindingFlags.Public)) 
    { 
     if (prop.CanRead && prop.CanWrite && prop.PropertyType == typeof(string) 
      && (prop.GetIndexParameters().Length == 0)) // watch for indexers! 
     { 
      var s = (string)prop.GetValue(obj, null); 
      if (!string.IsNullOrEmpty(s)) s = s.Trim(); 
      prop.SetValue(obj, s, null); 
     } 
    } 
+0

Loại không có tham số 'Loại.GetProperties() 'cuộc gọi bao gồm các thuộc tính tĩnh, mà tôi * nghi ngờ * không nên được bao gồm ở đây. –

+1

@Jon - tốt, cảm ơn. Tôi sẽ không đề cập đến 'IsReadable'; p Ngoài ra - bạn có thể muốn kiểm tra các chỉ mục. –

+0

@Marc: Sẽ sửa lỗi :) –

0

Vì vậy, để mở rộng về vấn đề này một chút, tôi có một đối tượng phức tạp với Danh mục Lists và tôi muốn đi qua đó và cắt tất cả các chuỗi đối tượng trẻ em là tốt. Tôi đăng những gì tôi đã làm kể từ những gì tôi xây dựng từ @Jon đã làm trong câu trả lời của mình. Tôi tò mò nếu có một cách tốt hơn để làm điều đó hoặc nếu tôi bỏ lỡ một cái gì đó hiển nhiên.

Các đối tượng tôi có phức tạp hơn điều này nhưng cần minh họa những gì tôi đang cố gắng.

public class Customer 
{ 
    public string Name { get; set; } 
    public List<Contact> Contacts { get; set; } 
} 

public class Contact 
{ 
    public string Name { get; set; } 
    public List<Email> EmailAddresses {get; set;} 
} 

public class Email 
{ 
    public string EmailAddress {get; set;} 
} 


    private void TrimWhitespace(object instance) 
    { 
     if (instance != null) 
     { 
      var props = instance.GetType() 
        .GetProperties(BindingFlags.Instance | BindingFlags.Public) 
       // Ignore indexers 
        .Where(prop => prop.GetIndexParameters().Length == 0) 
       // Must be both readable and writable 
        .Where(prop => prop.CanWrite && prop.CanRead); 

      foreach (PropertyInfo prop in props) 
      { 
       if (instance is IEnumerable) 
       { 
        foreach (var item in (IEnumerable)instance) 
        { 
         TrimWhitespace(item); 
        } 
       } 
       else if (prop.GetValue(instance, null) is string) 
       { 
        string value = (string)prop.GetValue(instance, null); 
        if (value != null) 
        { 
         value = value.Trim(); 
         prop.SetValue(instance, value, null); 
        } 
       } 
       else 
        TrimWhitespace(prop.GetValue(instance, null)); 
      } 
     } 
    } 

Suy nghĩ?

1

Không cần thiết để thực hiện IEnumerable kiểm tra vòng lặp đạo cụ và nếu trường hợp thực tế là IEnumerable, các đạo cụ sẽ bị bỏ qua. Khắc phục cho IEnumerable một phần:

private void TrimWhitespace(object instance) 
{ 
    if (instance != null) 
    { 
     if (instance is IEnumerable) 
     { 
      foreach (var item in (IEnumerable)instance) 
      { 
       TrimWhitespace(item); 
      } 
     } 

     var props = instance.GetType() 
       .GetProperties(BindingFlags.Instance | BindingFlags.Public) 
      // Ignore indexers 
       .Where(prop => prop.GetIndexParameters().Length == 0) 
      // Must be both readable and writable 
       .Where(prop => prop.CanWrite && prop.CanRead); 

     foreach (PropertyInfo prop in props) 
     { 
      if (prop.GetValue(instance, null) is string) 
      { 
       string value = (string)prop.GetValue(instance, null); 
       if (value != null) 
       { 
        value = value.Trim(); 
        prop.SetValue(instance, value, null); 
       } 
      } 
      else 
       TrimWhitespace(prop.GetValue(instance, null)); 
     } 
    } 
} 
Các vấn đề liên quan