程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#集合對象的屬性賦值

C#集合對象的屬性賦值

編輯:關於C#

(一)前言

繼《對象屬性之間的相互賦值 》後,關於集合對象屬性的賦值,主要可以通過循環遍歷集合中的對象來進行屬性間的賦值。這些可以運用於不同對象之間、相關屬性類似的情況。最常見的是web services與silverlight之間的對象賦值(對象之間的屬性值只有一部分是需要的),這樣可以減少silverlight對web services的依賴。

(二)具體實現

通過反射將源對象與目標對象之間的屬性賦值。源對象的屬性名、屬性類型必須與目標對象的屬性名、屬性類型一致,並且源對象的屬性必須是可讀的,目標對象的屬性是可寫的(僅針對於需要賦值的屬性來說)。具體的源代碼如下:

public class ObjectMapper  
    {
        private static readonly Dictionary<string, IList<PropertyMapper>> _mappers =
            new Dictionary<string, IList<PropertyMapper>>();
    
        public static IList<PropertyMapper> GetMapperProperties(
            Type sourceType, Type targetType)
        {
            var sourceProperties = sourceType.GetProperties();
            var targetProperties = targetType.GetProperties();
    
            return (from s in sourceProperties
                    from t in targetProperties
                    where s.Name == t.Name && s.CanRead && t.CanWrite && s.PropertyType == t.PropertyType
                    select new PropertyMapper
                              {
                                  SourceProperty = s,
                                  TargetProperty = t
                              }).ToList();
        }
    
        public static void CopyProperties<T1, T2>(List<T1> sources, List<T2> targets) where T2:new()
        {
            if (sources == null || sources.Count == 0 || targets == null)
            {
                return;
            }
    
            T2 target;
            foreach (T1 source in sources)
            {
                target = new T2();
                CopyProperties(source, target);
                targets.Add(target);
            }
        }
    
        public static void CopyProperties(object source, object target)
        {
            if (source == null || target == null)
            {
                return;
            }
            var sourceType = source.GetType();
            var targetType = target.GetType();
            string key = GetMapperKey(sourceType, targetType);
            if (!_mappers.ContainsKey(key))
            {
                MapperProperties(sourceType, targetType);
            }
    
            var mapperProperties = _mappers[key];
    
            SetPropertityValue(source, target, mapperProperties);
        }
    
        private static void SetPropertityValue(object source, 
            object target, IList<PropertyMapper> mapperProperties)
        {
            for (int index = 0, count = mapperProperties.Count; index < count; index++)
            {
                var property = mapperProperties[index];
                var sourceValue = property.SourceProperty.GetValue(source, null);
                property.TargetProperty.SetValue(target, sourceValue, null);
            }
        }
    
        protected static string GetMapperKey(Type sourceType, Type targetType)
        {
            return string.Format("{0}_{1}", sourceType.FullName,
                targetType.FullName);
        }
    
        public static void MapperProperties(Type source, Type target)
        {
            if (source == null || target == null)
            {
                return;
            }
    
            string key = GetMapperKey(source, target);
            if (_mappers.ContainsKey(key))
            {
                return;
            }
    
            var properties = GetMapperProperties(source, target);
            _mappers.Add(key, properties);
        }
    }

有效的方法主要為如下2個:

(1)第22-36行CopyProperties<T1, T2>(List<T1> sources, List<T2> targets) where T2:new()

目標對象集合必須添加約束(where T2:new())---必須有默認構造函數。從如下的代碼可以看出 target = new T2()必須通過實例化,才能將其添加到目標集合中。

T2 target;

30             foreach (T1 source in sources)

31             {

32                 target = new T2();

33                 CopyProperties(source, target);

34                 targets.Add(target);

35             }

(2)CopyProperties(object source, object target)

這個方法才是最關鍵的,因為集合對象之間的賦值主要是通過循環該方法來賦值的。

(三)單元測試

對象集合對象之間的賦值,相關的單元測試代碼如下(僅考慮了簡單的對象),通過下面的測試,可以檢測到集合對象屬性賦值賦值後,值是相同的:

[TestMethod()]
        public void CopyPropertiesTest1()
        {
            List<Jasen.Core.Info> sources = new List<Core.Info>();
            for (int index = 0; index < 10; index++)
            {
                sources.Add(new Jasen.Core.Info()
                {
                    Name = "jasen",
                    CreateTime = "2011-5-13".AsDateTime(),
                    Exist = true,
                    ConflictOption = ConflictOption.OverwriteChanges,
                    Index = index
                });
            }
            List<Info> targets = new List<Info>();    
            ObjectMapper.CopyProperties(sources, targets);
            for (int index = 0, count = sources.Count; index < count; index++)
            {
                Assert.AreEqual(sources[index].ConflictOption, targets[index].ConflictOption);
                Assert.AreEqual(sources[index].CreateTime, targets[index].CreateTime);
                Assert.AreEqual(sources[index].Exist, targets[index].Exist);
                Assert.AreEqual(sources[index].Name, targets[index].Name);
                //Assert.AreEqual(sources[index].Index, targets[index].Index);
            }
        }

(四)總結

以上的代碼僅僅針對於簡單的屬性之間的賦值,對於對象包含IList集合屬性的賦值,可以將該IList再進行一次賦值即可。上文中采用字典來使性能提高,當第一次賦值的時候保存需要賦值的相關聯的屬性對集合。第二次的時候就直接通過鍵值獲取該屬性對,不需要再次查找相關的屬性對集合。

源代碼下載:Jasen.CopyObjectToObjectSample.rar

http://files.cnblogs.com/jasenkin/Jasen.CopyObjectToObjectSample.rar

作者:JasenKin

出處:http://www.cnblogs.com/jasenkin/

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved