将ExpandoObject转换为T的AnonymousType

时间:2019-05-10 00:14:06

标签: c# system.reflection

我正在尝试克隆AnonymousType并进行一些奇怪的行为。

谁能告诉我原因,也可以告诉我解决方案。 这是测试代码。

 public static T DeepClone<T>(this T objectToBeCloned) where T : class
        {
            // this will always return null.
            return Clone(objectToBeCloned) as T;

            // if i try, it will work somehow
            // var o = Clone(objectToBeCloned) as dynamic;

            // if I try, will get an exception cant cast 
            // ExpandoObject to AnonymousType even thaugh i could cast it to dynamic  
            // var o = (T)Clone(objectToBeCloned);
        }


       // the clone method 
       public static object Clone(this object objectToBeCloned){
        object resObject;
        if (primaryType.IsAnonymousType()) // dynamic types
            {

                var props = FastDeepClonerCachedItems.GetFastDeepClonerProperties(primaryType);
                resObject = new ExpandoObject();
                var d = resObject as IDictionary<string, object>;
                foreach (var prop in props.Values)
                {
                    var item = prop.GetValue(objectToBeCloned);
                    if (item == null)
                        continue;
                    var value = prop.IsInternalType ? item : Clone(item);
                    if (!d.ContainsKey(prop.Name))
                        d.Add(prop.Name, value);
                }
       return resObject;
       }


       dynamic test = { p1="sd" };
       var v =test.DeepClone(test);
       // v is always null in this case dont understand why 

1 个答案:

答案 0 :(得分:0)

这不是最干净的代码,但是会克隆一个匿名类型:

var original = new  { Name = "Albert", Age = 99 };

var constructor = original.GetType().GetConstructors().First();

var parameters = constructor.GetParameters();

var properties = original.GetType().GetProperties();

var arguments =
(
    from pa in parameters
    join pr in properties on pa.Name equals pr.Name
    select pr.GetValue(original)
).ToArray();

var clone = constructor.Invoke(arguments);

由于匿名类型是不可变的,因此使用不多。