简体   繁体   English

Activator.CreateInstance与字符串

[英]Activator.CreateInstance with string

I'm trying to populate a generic List< T > from another List< U > where the field names match, something like the untested pseudocode below. 我试图从字段名称匹配的另一个List <U>填充通用List <T>,类似于下面未经测试的伪代码。 Where I'm having problems is when T is a string, for instance, which has no parameterless constructor. 我遇到问题的地方是例如T是一个字符串,它没有无参数构造函数。 I've tried adding a string directly to the result object, but this gives me the obvious error -- that a string is not of Type T. Any ideas of how to solve this issue? 我尝试将字符串直接添加到结果对象,但这给了我一个明显的错误-字符串不是TypeT。关于如何解决此问题的任何想法? Thanks for any pointers. 感谢您的指导。

    public static List<T> GetObjectList<T, U>(List<U> givenObjects)
    {
        var result = new List<T>();

        //Get the two object types so we can compare them.
        Type returnType = typeof(T);
        PropertyInfo[] classFieldsOfReturnType = returnType.GetProperties(
           BindingFlags.Instance |
           BindingFlags.Static |
           BindingFlags.NonPublic |
           BindingFlags.Public);

        Type givenType = typeof(U);
        PropertyInfo[] classFieldsOfGivenType = givenType.GetProperties(
           BindingFlags.Instance |
           BindingFlags.Static |
           BindingFlags.NonPublic |
           BindingFlags.Public);

        //Go through each object to extract values
        foreach (var givenObject in givenObjects)
        {

            foreach (var field in classFieldsOfReturnType)
            {
                //Find where names match
                var givenTypeField = classFieldsOfGivenType.Where(w => w.Name == field.Name).FirstOrDefault();

                if (givenTypeField != null)
                {
                    //Set the value of the given object to the return object
                    var instance = Activator.CreateInstance<T>();
                    var value = field.GetValue(givenObject);

                    PropertyInfo pi = returnType.GetProperty(field.Name);
                    pi.SetValue(instance, value);

                    result.Add(instance);
                }

            }
        }

        return result;
    }

If T is string and you have already created custom code to convert your givenObject to a string, you just need to do an intermediate cast to object to add it to a List<T> : 如果Tstring并且您已经创建了自定义代码, givenObject转换为字符串,则只需对object进行中间转换,即可将其添加到List<T>

    public static List<T> GetObjectList2<T, U>(List<U> givenObjects) where T : class
    {
        var result = new List<T>();

        if (typeof(T) == typeof(string))
        {
            foreach (var givenObject in givenObjects)
            {
                var instance = givenObject.ToString();  // Your custom conversion to string.
                result.Add((T)(object)instance);
            }
        }
        else
        {
            // Proceed as before
        }

        return result;
    }

Incidentally, you are adding an instance of T to result for every property of T that matches a property name in U and for every item in givenObjects . 顺便说一句,您要添加一个instanceT ,以result针对每个属性 T ,在匹配的属性名U并为每个项目givenObjects Ie if givenObjects is a list of length 1 and T is a class with 10 matching properties, result could end up with 10 entries. 即,如果givenObjects是长度为1的列表,而T是具有10个匹配属性的类,则result可能以10个条目结束。 This looks wrong. 这看起来不对。 Also, you need to watch out for indexed properties . 另外,您需要注意索引属性

As an alternative to this approach, consider using Automapper , or serializing your List<U> to JSON with Json.NET then deserializing as a List<T> . 作为此方法的替代方法,请考虑使用Automapper ,或使用Json.NET将List<U>序列化为JSON,然后反序列化为List<T>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM