0
votes

I try to use Xamarin Forms (with PCL project). My scope is to make an app to consume public service (exposed via web services). I try to use TODOASMX Example of Xamarin website. The problem is the code:

static TodoItem FromASMXServiceTodoItem (ASMXService.TodoItem item)
    {
        return new TodoItem {
            ID = item.ID,
            Name = item.Name,
            Notes = item.Notes,
            Done = item.Done
        };
    }

scope of this code is to copy data from ASMX web Service (ASMXService.TodoItem ) to private domanin (TodoItem). The types are identical, but on namespace different and than the type are different.

In my case the type TodoItem is more, more , more complicated and I need to use a deep copy. Now I try to use this code for deep copy:

public static object CloneObject(object objSource)

    {

        //step : 1 Get the type of source object and create a new instance of that type

        Type typeSource = objSource.GetType();

        object objTarget = Activator.CreateInstance(typeSource);



        //Step2 : Get all the properties of source object type

        PropertyInfo[] propertyInfo = typeSource.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);



        //Step : 3 Assign all source property to taget object 's properties

        foreach (PropertyInfo property in propertyInfo)

        {

            //Check whether property can be written to 

            if (property.CanWrite)

            {

                //Step : 4 check whether property type is value type, enum or string type

                if (property.PropertyType.IsValueType || property.PropertyType.IsEnum || property.PropertyType.Equals(typeof(System.String)))

                {

                    property.SetValue(objTarget, property.GetValue(objSource, null), null);

                }

                //else property type is object/complex types, so need to recursively call this method until the end of the tree is reached

                else

                {

                    object objPropertyValue = property.GetValue(objSource, null);

                    if (objPropertyValue == null)

                    {

                        property.SetValue(objTarget, null, null);

                    }

                    else

                    {

                        property.SetValue(objTarget, CloneObject(objPropertyValue), null);

                    }

                }

            }

        }

        return objTarget;

    }

but when run the code the error is:

System.MissingMethodException: Default constructor not found for type TodoASMX.Droid.MeginetOTA.excInfoByLang[]

Now the type TodoASMX.Droid.MeginetOTA.excInfoByLang[] is not modificable for me and I cannot add default constructor to this type. This type is returned by import of public WebService.

Any workaround (or solution) is appreciated.

Very thanks in advance.

MP

1
How does the constructor of this type look?Sven-Michael Stübe

1 Answers

0
votes

The primary problem is that TodoASMX.Droid.MeginetOTA.excInfoByLang[] is an array. A array has no parameterless constructor, because you need to pass the length of it.

You have to handle arrays separately:

if (typeSource.IsArray)
{
    var sourceArray = (Array) objSource;
    var length = sourceArray.Length;
    var copyArray = (Array)Activator.CreateInstance(typeSource, length);

    for (var i = 0; i < length; i++)
    {
        var value = sourceArray.GetValue(i);
        copyArray.SetValue(value, i);
    }
}

You approach is maybe a bit complicated. Have a look at https://stackoverflow.com/a/78612/1489968 or search for a already implemented generic clone library.