找不到属性集方法

时间:2014-02-12 07:45:42

标签: c# reflection collections

当此行 bckPk =翻译(包); 执行时,我找不到属性集方法。错误很自然。但有人可以建议我解决这个问题,通过这个方法,我可以实现我在这里尝试做的事情吗?

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

编辑:这里我想使用Reflection将包中的对象复制到bckPk,而不是使用foreach循环。例如,采用以下示例:

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 个答案:

答案 0 :(得分:1)

您正在获取异常,因为您正在尝试将值设置为ReadOnly属性。 即,仅使用吸气剂定义的属性。

这里你忘记了继承,因为你的类继承了基类Collection<T>类,你得到了异常

当您尝试阅读ClassPack中的所有属性并在ClassBckPack中设置时,他们继承了名为Count的成员,该成员是只读的,这意味着它不会定义Set 1}}方法。所以你得到了上述例外。

请阅读System.Collections.ObjectModel

中的以下API
 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)
            {
             }
         }

我觉得这很有道理。 感谢