-1

Im trying to clone an AnonymousType and enconter some strange behavior.

could anyone tell me why and also tell me a solution. Here is a test code.

 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 
Alen.Toma
  • 4,684
  • 2
  • 14
  • 31
  • An anonymous type isn't dynamic. The compiler creates a static type at compile-time. An `ExpandoObject` is created at run-time. They are two different things. You can't cast them to each other. – Enigmativity May 10 '19 at 02:12
  • I see, what is the best way to resolve this situation do you think? I created a new method `DynamicClon` which will return a anonymous type, is there a better way? – Alen.Toma May 10 '19 at 04:37
  • Why do you want to clone an anonymous type anyway? They are immutable reference types. Clones don't make sense to me. – Enigmativity May 10 '19 at 04:53
  • Not sure of that my self but i have a library `FastDeepCloner` and someone wanted to be able to clone anonymous type. which i think that every one have its reason. Anyway i already solved this problem by creating s seperate method DynamicClone() which return `ExpandoObject` this should satisfy the user at least. – Alen.Toma May 10 '19 at 05:12

1 Answers1

0

This isn't the cleanest code, but it clones an anonymous type:

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

Not much use though as anonymous types are immutable.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172