2014-02-12 56 views
3

當這一行bckPk = Translate(packs);執行我得到未找到屬性集方法。這是很自然的錯誤。但有人可以建議我一個解決方法,我可以通過這個解決方案實現我在這裏要做的事情嗎?找不到屬性設置方法

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Collections; 
using System.Reflection; 

namespace ExperimentProjects 
{ 
    public class ClassOne 
    { 
     public string PropertyOne { get; set; } 
     public string PropertyTwo { get; set; } 
     public string PropertyThree { get; set; } 
    } 
    public class ClassTwo 
    { 
     public string PropertyOne { get; set; } 
     public string PropertyTwo { get; set; } 
     public string PropertyThree { get; set; } 

    } 

    public class ClassPack : Collection<ClassOne> 
    { 

    } 

    public class ClassBckPack : Collection<ClassOne> 
    { 

    } 
    public class TranslateClass 
    { 
     public static TResult Translate<TSource, TResult>(TSource sourceObj) 
     { 

      Type typeOfSourceObj = sourceObj.GetType(); 
      Type typeOfResultObj = typeof(TResult); 
      if (typeOfSourceObj.BaseType.Equals(typeOfResultObj.BaseType)) 
      { 
       //Console.WriteLine("1"); 

      } 

      ConstructorInfo constructorOfresultObj = typeOfResultObj.GetConstructor(System.Type.EmptyTypes); 
      Object[] parameters = new Object[0]; 
      TResult result = (TResult)constructorOfresultObj.Invoke(parameters); 
      PropertyInfo[] propertiesInSourceObj = typeOfSourceObj.GetProperties(); 
      if (propertiesInSourceObj.Length != 0) 
      { 
       foreach (PropertyInfo property in propertiesInSourceObj) 
       { 
        Console.WriteLine(property.PropertyType.Name); 
        PropertyInfo propertyOfResultObj = typeOfResultObj.GetProperty(property.Name); 

        if (propertyOfResultObj != null) 
        { 
         propertyOfResultObj.SetValue(result, property.GetValue(sourceObj)); 
        } 
       } 
      } 

      Console.Read(); 
      return result; 
     } 
     static void Main(string[] args) 
     { 
      ClassOne objOne = new ClassOne(); 
      objOne.PropertyOne = "One"; 
      objOne.PropertyTwo = "Two"; 
      objOne.PropertyThree = "Three"; 
      ClassTwo objTwo = Translate<ClassOne, ClassTwo>(objOne); 
      Console.WriteLine(objTwo.PropertyOne + " " + objTwo.PropertyTwo + " " + objTwo.PropertyThree); 
      ClassOne o = Translate<ClassOne, ClassOne>(objOne); 
      Console.WriteLine(o.PropertyOne + " " + o.PropertyTwo + " " + o.PropertyThree); 
      ClassPack packs = new ClassPack(); 
      packs.Add(o); 
      packs.Add(objOne); 

      ClassBckPack bckPk = null; 
      try 
      { 
       bckPk = Translate<ClassPack, ClassBckPack>(packs); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine(e.Message); 
       Console.Read(); 
      } 
      foreach (ClassOne eachObj in bckPk) 
       Console.WriteLine(eachObj.PropertyOne + " " + eachObj.PropertyTwo + " " + eachObj.PropertyThree); 
      Console.Read(); 
     } 
    } 
} 

編輯:在這裏我想複製對象從包使用反射,而不是使用foreach循環的bckPk。例如藉此下面的例子:

Class Content 
{ 

} 

Class AContents : Collection<Content> 
{ 
} 

Class BContents : Collection<Content> 
{ 
} 

Class BusinessEntity 
{ 
    public AContents 
    { 
     get; set; 
    } 
} 
Class DataContract 
{ 
    public AContents 
    { 
    get; set; 
    } 
} 

I want to use this Translate method this way now : 

BusinessEntity be= new BusinessEntity(); 
DataContract dc= new DataContract(); 

dc=Translate<BusinessEntity,DataContract>(be); 

如果我運行這個代碼,那麼就會拋出屬性設置方法沒有找到錯誤

+1

那你究竟在做什麼?它試圖在這種情況下設置Count屬性......您可以很容易地判斷某個屬性是否可寫(使用CanWrite屬性),但我認爲這不會對您有太大的幫助。 –

+0

這只是我的印象,但對於泛型方法使用這麼多反射感覺不對。在某些情況下,當然可能有必要。 – Dirk

+0

請參閱編輯後文章 –

回答

1

你得到,因爲你試圖將值設置爲只讀異常屬性。 即,僅用getter定義的屬性。

在這裏,你忘了的傳承,因爲你的類是從基Collection<T>類繼承你所得到的例外

當你試圖讀取ClassPack所有屬性和ClassBckPack設置,他們繼承的成員稱爲Count這是隻讀的,這意味着它沒有定義Set方法。所以你得到了上述例外。

請閱讀System.Collections.ObjectModel

public class Collection<T> : IList<T>, ICollection<T>, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable 
{ 
    // Summary: 
    //  Initializes a new instance of the System.Collections.ObjectModel.Collection<T> 
    //  class that is empty. 
    [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] 
    public Collection(); 
    // 
    // Summary: 
    //  Initializes a new instance of the System.Collections.ObjectModel.Collection<T> 
    //  class as a wrapper for the specified list. 
    // 
    // Parameters: 
    // list: 
    //  The list that is wrapped by the new collection. 
    // 
    // Exceptions: 
    // System.ArgumentNullException: 
    //  list is null. 
    public Collection(IList<T> list); 

    // Summary: 
    //  Gets the number of elements actually contained in the System.Collections.ObjectModel.Collection<T>. 
    // 
    // Returns: 
    //  The number of elements actually contained in the       ****System.Collections.ObjectModel.Collection<T>. 
    public int Count { get; }**** 
    // 
    // Summary: 
    //  Gets a System.Collections.Generic.IList<T> wrapper around the System.Collections.ObjectModel.Collection<T>. 
    // 
    // Returns: 
    //  A System.Collections.Generic.IList<T> wrapper around the System.Collections.ObjectModel.Collection<T>. 
    protected IList<T> Items { get; } 

所以這裏的下列API的工作都是圍繞

創建CustomAttribute說「ExampleAttribute」,只適用於那些你想從源類更新屬性以目標課爲目標。然後閱讀所有屬性檢查屬性是否屬於新屬性的類型。多數民衆贊成你如何diffrentiate基類的屬性從你的子類。

foreach (PropertyInfo propertyInfo in type.GetProperties()) 
     { 
      object[] attrObjs = propertyInfo.GetCustomAttributes(typeof(ExampleAttribute), true); 
      if (attrObjs.Length > 0) 
      { 
      } 
     } 

我覺得這很有道理。 謝謝

+0

是的,我知道了。現在你能向我提供一種讓翻譯發生的方式嗎? –

+0

請參閱編輯帖子並將其標記爲答案 – Srikanth

0

我還想提出我的新發現的知識,當你在多個地方使用AutoMap時,它已經在更深的層次上創建了映射,然後當你從另一個角度調用它時,它會完全搞砸:呈現相同的錯誤。