Cast class into another class or convert class to another

Viewed 186767

My question is shown in this code

I have class like that

public class MainCS
{
  public int A;
  public int B;
  public int C;
  public int D; 
}

public class Sub1
{
  public int A;
  public int B;
  public int C;
}


public void MethodA(Sub1 model)
{
  MainCS mdata = new MainCS() { A = model.A, B = model.B, C = model.C };   

  // is there a way to directly cast class Sub1 into MainCS like that    
  mdata = (MainCS) model;    
}
11 Answers

Using this code you can copy any class object to another class object for same name and same type of properties.

JavaScriptSerializer JsonConvert = new JavaScriptSerializer(); 
string serializeString = JsonConvert.Serialize(objectEntity);
objectViewModel objVM = JsonConvert.Deserialize<objectViewModel>(serializeString);
var obj =  _account.Retrieve(Email, hash);

AccountInfoResponse accountInfoResponse = new AccountInfoResponse();

if (obj != null)
{               
   accountInfoResponse = 
   JsonConvert.
   DeserializeObject<AccountInfoResponse>
   (JsonConvert.SerializeObject(obj));
}

image description

I tried to use the Cast Extension (see https://stackoverflow.com/users/247402/stacker) in a situation where the Target Type contains a Property that is not present in the Source Type. It did not work, I'm not sure why. I refactored to the following extension that did work for my situation:

public static T Casting<T>(this Object source)
{
    Type sourceType = source.GetType();
    Type targetType = typeof(T);
    var target =  Activator.CreateInstance(targetType, false);
    var sourceMembers = sourceType.GetMembers()
        .Where(x => x.MemberType  == MemberTypes.Property)
        .ToList();
    var targetMembers = targetType.GetMembers()
        .Where(x => x.MemberType == MemberTypes.Property)
        .ToList();
    var members = targetMembers
        .Where(x => sourceMembers
            .Select(y => y.Name)
                .Contains(x.Name));
    PropertyInfo propertyInfo;
    object value;
    foreach (var memberInfo in members)
    {
        propertyInfo = typeof(T).GetProperty(memberInfo.Name);
        value = source.GetType().GetProperty(memberInfo.Name).GetValue(source, null);
        propertyInfo.SetValue(target, value, null);
    }
    return (T)target;
}

Note that I changed the name of the extension as the Name Cast conflicts with results from Linq. Hat tip https://stackoverflow.com/users/2093880/usefulbee

I developed a Class ObjectChanger that contains the functions ConvertToJson, DeleteFromJson, AddToJson, and ConvertToObject. These functions can be used to convert a C# object to JSON which properties can then be removed or added accordingly. Afterwards the adjusted JSON object can simply be converted to a new object using ConvertToObject function. In the sample code below the class "AtoB" utilizes ObjectChanger in its GetAtoB() function:

using System.Collections.Generic;
using Newtonsoft.Json;
using Nancy.Json;
namespace YourNameSpace
{
public class A
{
    public int num1 { get; set; }
    public int num2 { get; set; }
    public int num3 { get; set; }
}
public class B//remove num2 and add num4
{
    public int num1 { get; set; }
    public int num3 { get; set; }
    public int num4 { get; set; }
}
/// <summary>
/// This class utilizes ObjectChanger to illustrate how
/// to convert object of type A to one of type B
/// by converting A to a Json Object, manipulating the JSON
/// and then converting it to object of type B
/// </summary>
public class AtoB
{
    public dynamic GetAtoB()
    {
        A objectA = new A
        {
            num1 =1, num2 =2,num3 =3
        };
        //convert "objectA" to JSON object "jsonA"
        dynamic jsonA = ObjectChanger.ConvertToJson(objectA);
        //remove num2 from jsonA
        ObjectChanger.DeleteFromJson(jsonA, "num2");
        //add property num4 with value 4 to jsonA
        ObjectChanger.AddToJson(jsonA, "num4", 4);

        B objectB = ObjectChanger.ConvertToObject<B>(jsonA);

        return objectB;
       
        //note: Above DeleteFromJson not needed if the 
        //property(e.g "num2") doesn't exist in objectB   
        //the jsonA will still keep the num2 but when
        //ConvertToObject is called the objectB will only get 
        //populated with the relevant fields.
    }
}
public class ObjectChanger
{
    /// <summary>
    /// Converts a provided class to JsonObject
    /// sample use: dynamic r = ObjectChanger.ConvertToJson(providedObj);
    /// </summary>
    public static dynamic ConvertToJson(dynamic providedObj)
    {
        JsonSerializerSettings jss = new JsonSerializerSettings();
        jss.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
        //https://stackoverflow.com/questions/7397207/json-net-error-self-referencing-loop-detected-for-type
        return JsonConvert.DeserializeObject<System.Dynamic.ExpandoObject>
               (JsonConvert.SerializeObject(providedObj,jss));
        
    }
    /// <summary>
    /// Deletes Property from Json Object
    /// sample use: dynamic r = ObjectChanger.ConvertToJson(providedObj);
    /// ((IDictionary<string, object>)r).Remove("keyvalue");
    /// </summary>
    public static dynamic DeleteFromJson(dynamic providedObj, string keyvalue)
    {
        ((IDictionary<string, object>)providedObj).Remove(keyvalue);
        return providedObj;
    }
    /// <summary>
    /// Adds Property to provided Json Object
    /// </summary>
    /// <param name="providedObj"></param>
    /// <param name="key"></param>
    /// <param name="keyvalue"></param>
    /// <returns>Returns updated Object</returns>
    public static dynamic AddToJson(dynamic providedObj, string key, 
    dynamic keyvalue)
    {
        ((IDictionary<string, object>)providedObj).Add(key, keyvalue);
        return providedObj;
    }
    /// <summary>
    /// Converts provided object providedObj 
    /// to an object of type T
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="providedObj"></param>
    /// <returns></returns>
    public static T ConvertToObject<T>(dynamic providedObj)
    {
        var serializer = new JavaScriptSerializer();
        var json = serializer.Serialize(providedObj);
        var c = serializer.Deserialize<T>(json);
        return c;
    }
}
}
Related