2014-02-12 2 views
3

Когда эта строка bckPk = Translate (пакеты); Выполняет Я получаю Метод набора свойств не найден. ошибка, которая довольно естественна. Но может ли кто-нибудь предложить мне обходное решение для этого, которым я могу достичь того, что я пытаюсь сделать здесь?Метод определения объекта не найден

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(); 
     } 
    } 
} 

EDIT: Вот я хочу, чтобы скопировать объект из пакетов в 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

Вы получаете исключение, потому что вы пытаетесь установить значение в ReadOnly имущество. т. Е. Свойство, определенное только с геттером.

здесь вы забыли о наследовании, так как ваш класс наследуют от базовых Collection<T> класса вы получаете исключение

Как вы пытаетесь прочитать все свойства в ClassPack и установить в ClassBckPack, они унаследовали член называется Count, который является readonly, что означает, что он не определяет метод Set. Таким образом, вы получаете исключение выше.

Пожалуйста, прочтите следующую API от 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; } 

Так вот работа вокруг

Создать CustomAttribute сказать «ExampleAttribute» и применять только те свойства, которые вы пытаетесь обновить из исходного класса для целевого класса. Затем Прочитайте все свойства, проверьте, является ли свойство типом вашего нового атрибута. Вот как вы будете отличать свойства базового класса от вашего дочернего класса.

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

Я чувствую, что это имеет смысл. спасибо

+0

Да, я понял. Теперь вы можете предложить мне способ, которым я делаю перевод? –

+0

См. Редактировать сообщение и отметить как ответ – Srikanth

0

Я также хотел бы предложить свои новые знания о том, что при использовании AutoMap в нескольких местах он уже создает сопоставление на более глубоком уровне, а затем, когда вы вызываете его из другой точки, он становится полностью испорченным: представляя ту же ошибку.

Смежные вопросы