.NET Reflection 反射 類屬性間的拷貝

weixin_33858249發表於2017-11-11

This code sample demonstrates how to copy class properties from one class to another even if they are not the same type. It also demonstrates how to validate a class's required properties dynamically. Both of these can increase your coding productivity especially when dealing with web service versions of your business classes.

PropertyHandler.cs
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Diagnostics;

namespace MyApplication
{
    public class PropertyHandler
    {
        #region Set Properties
        public static void SetProperties(PropertyInfo[] fromFields,
                                         PropertyInfo[] toFields,
                                         object fromRecord,
                                         object toRecord)
        {
            PropertyInfo fromField = null;
            PropertyInfo toField = null;

            try
            {

                if (fromFields == null)
                {
                   return;
                }
                if (toFields == null)
                {
                   return;
                }

                for (int f = 0; f < fromFields.Length; f++)
                {

                    fromField = (PropertyInfo)fromFields[f];

                    for (int t = 0; t < toFields.Length; t++)
                    {

                        toField = (PropertyInfo)toFields[t];

                        if (fromField.Name != toField.Name)
                        {
                            continue;
                        }

                        toField.SetValue(toRecord,
                                         fromField.GetValue(fromRecord, null),
                                         null);
                        break;

                    }

                }
 
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

        #region Set Properties
        public static void SetProperties(PropertyInfo[] fromFields,
                                         object fromRecord,
                                         object toRecord)
        {
            PropertyInfo fromField = null;
         
            try
            {

                if (fromFields == null)
                {
                    return;
                }

                for (int f = 0; f < fromFields.Length; f++)
                {

                    fromField = (PropertyInfo)fromFields[f];

                    fromField.SetValue(toRecord,
                                       fromField.GetValue(fromRecord, null),
                                       null);
                }

            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion
  
        
    }
} 
PropertyHandler Sample For Identical Classes
MyClass record = new MyClass();
MyClass newRecord = new MyClass();
PropertyInfo[] fromFields = null;

fromFields = typeof(MyClass).GetProperties();

PropertyHandler.SetProperties(fromFields, record, newRecord);
 
PropertyHandler Sample For Similar Classes
 
MyClass record = new MyClass();
MyOtherClass newRecord = new MyOtherClass();
PropertyInfo[] fromFields = null;
PropertyInfo[] toFields = null;

fromFields = typeof(MyClass).GetProperties();
toFields = typeof(MyOtherClass).GetProperties();

PropertyHandler.SetProperties(fromFields,toFields,record, newRecord);
 
Self Validation Methods
// Some of the code below relies on runtime reflection.  Certain aspects
// of reflection are detrimental to performance.  Where possible, you
// can create static instances of the reflection results.  It will give
// the power without the overhead of using reflection.

 // Here is a sample business class layer self validation method.

 
 private bool ValidateSave(CellAlignment record)
 {
 
   object[,] properties = null;
   List<string> returnMessages = new List<string>();

   try
   {

     // Use the .GetFields() method mentioned later in this sample.

     properties = this.GetFields(this.GetType());

     if (!record.ValidateRequiredProperties(properties,
                                            returnMessages))
     {
        for (int i = 0; i < returnMessages.Count; i++)
        {
           Debug.WriteLine(returnMessages[i]);
        }
        return false;
     }

   }
   catch (Exception) { throw;}
   return true;
 
 }
 



 // This code was extracted from the ADO.NET Code Generator mentioned
 // above.

 // Here is a sample property to demonstrate how to use the
 // ColumnAttributes class.  It sets this as being required
 // and tells the validator that it is an int data type.

 private int cellAlignmentID = 0;
 
 [ColumnAttributes("CellAlignmentID",true,"int")]
 public int CellAlignmentID
 {
   get 
   {
      return cellAlignmentID;
   }
   set 
   { 
      if (value != cellAlignmentID)
      { 
        cellAlignmentID = valuue;
      }
   }
 }





// The ColumnAttributes class itself.

 
[AttributeUsage(AttributeTargets.Property,AllowMultiple = true)] 
 public sealed class ColumnAttributes : System.Attribute  
 { 
 
   private string columnName;
   private bool isRequired;
   private string propertyType;
 
   public string ColumnName
   {
     get { return columnName; } 
   }
 
   public bool IsRequired
   {
     get { return isRequired; } 
   }
 
   public string PropertyType
   {
      get { return propertyType; } 
   }
 
   public ColumnAttributes(string columnNameValue,
                           bool isRequiredValue,
                           string propertyTypeValue)
   { 
      columnName = columnNameValue; 
      isRequired = isRequiredValue; 
      propertyType = propertyTypeValue; 
   } 
 
 } 




// Here is a method we can use to get an array of
// PropertyInfo objects as well as custom attributes.
// Make sure every class has this in method available
// to run on itself.  The ADO.NET Code Generator has
// this apart of the CustomAttributes.cs that all
// DataObjects inherit.

 
 public object[,] GetFields(Type t) 
 { 
 
   PropertyInfo[] fields = t.GetProperties(); 
   PropertyInfo field; 
   Attribute[] attributes; 
   object[,]  structureInfo = new object[fields.Length,2];  
 
   try 
   { 
      for(int i =0;i<fields.Length;i++) 
      {       
        field = fields[i];
        attributes =  Attribute.GetCustomAttributes(field,
                                           typeof(DataObjects.Tables.ColumnAttributes),
                                           false); 
        structureInfo[i,0] = field; 
        structureInfo[i,1] = attributes; 
      } 
   } 
   catch (Exception) { throw; } 
   return structureInfo; 
 } 
  
 
 public bool ValidateRequiredProperties(object[,] properties,
                                        List<string> returnMessages)
 {
    bool returnValue = true;
    PropertyInfo property;
    Attribute[] attributes;
    ColumnAttributes columnAttribute = null;

    try
    {


      if (properties == null)
      {
        throw new Exception("Please pass in the results of this.GetFields().");
      }
 
      if (returnMessages != null) 
      { 
         returnMessages.Clear(); 
      } 
 
      for (int i = 0; i <= properties.GetUpperBound(0); i++) 
      { 
 
          property = (PropertyInfo)properties[i, 0]; 
          attributes = (Attribute[])properties[i, 1]; 

          foreach (Attribute attribute in attributes) 
          { 

            columnAttribute = (ColumnAttributes)attribute; 

            if (!columnAttribute.IsRequired) 
            { 
              continue; 
            } 

            //    Debug.WriteLine(columnAttribute.ColumnName); 
           //     Debug.WriteLine(property.GetValue(this,null)); 

           if (!this.ValidateRequiredPropertyInfo(columnAttribute, 
                                                  property)) 
           { 

              returnValue = false; 

              if (returnMessages != null) 
              { 
                 returnMessages.Add(columnAttribute.ColumnName + " is required.");
              } 
           } 

         } 

     } 
     } 
     catch (Exception) { throw;}
     return returnValue;
   }
   
 
     public bool ValidateRequiredProperties(object[,] properties) 
     { 
        List<string> returnMessages = null; 

        try
        {
           return ValidateRequiredProperties(properties,
                                             returnMessages); 
        } 
        catch (Exception) { throw; } 
     } 
 
     public bool ValidateRequiredPropertyInfo(ColumnAttributes columnAttribute, 
                                              PropertyInfo property) 
     { 
        try 
        { 
          switch (columnAttribute.PropertyType.ToLower()) 
          { 

              case "int": 

                  if ((int)property.GetValue(this, 
                                        null) == 0) 
                  { 
                      return false; 
                  } 
                  
                  break; 

              case "int16": 

                  if ((Int16)property.GetValue(this, 
                                        null) == 0) 
                  { 
                      return false; 
                  } 
                  
                  break; 

              case "int32": 

                  if ((Int32)property.GetValue(this, 
                                        null) == 0) 
                  { 
                      return false; 
                  } 
                  
                  break; 

              case "int64": 

                  if ((Int64)property.GetValue(this, 
                                        null) == 0) 
                  { 
                      return false; 
                  } 
                  
                  break; 

              case "uint": 

                  if ((uint)property.GetValue(this, 
                                        null) == 0) 
                  { 
                      return false; 
                  } 
                  
                  break; 

              case "uint16": 

                  if ((UInt16)property.GetValue(this, 
                                        null) == 0) 
                  { 
                      return false; 
                  } 
                  
                  break; 

              case "uint32": 

                  if ((UInt32)property.GetValue(this, 
                                        null) == 0) 
                  { 
                      return false; 
                  } 
                  
                  break; 

              case "uint64": 

                  if ((UInt64)property.GetValue(this, 
                                        null) == 0) 
                  { 
                      return false; 
                  } 
                  
                  break; 

                case "double": 

                   if ((double)property.GetValue(this, 
                                                 null) == 0) 
                   { 
                       return false; 
                   } 

                   break; 

                 case "float": 

                     if ((float)property.GetValue(this, 
                                                  null) == 0) 
                     { 
                          return false; 
                     } 

                      break; 

                 case "single": 

                     if ((Single)property.GetValue(this, 
                                                  null) == 0) 
                     { 
                          return false; 
                     } 

                      break; 

                  case "string": 
                  
                      if ((string)property.GetValue(this, 
                                                    null) == String.Empty) 
                      {
                          return false; 
                      } 
                      
                      break; 

                  case "guid": 
                  
                      if ((Guid)property.GetValue(this, 
                                                  null) == Guid.Empty) 
                      {
                          return false; 
                      } 
                      
                      break;
                      

                  default: 

                      if (property.GetValue(this, 
                                            null) == null) 
                      { 
                          return false; 
                      } 
                      
                      break; 
              } 
            } 
            catch (Exception) { throw; } 
            return true; 
         } 
 
 

  本文轉自靈動生活部落格園部落格,原文連結:http://www.cnblogs.com/ywqu/archive/2009/01/04/1368445.html ,如需轉載請自行聯絡原作者

相關文章