cast class into another class or convert class to

2020-01-26 04:15发布

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 is a way to directly cast class sub1 into main like that    
  mdata = (maincs) model;    
}

9条回答
相关推荐>>
2楼-- · 2020-01-26 04:35

There are some great answers here, I just wanted to add a little bit of type checking here as we cannot assume that if properties exist with the same name, that they are of the same type. Here is my offering, which extends on the previous, very excellent answer as I had a few little glitches with it.

In this version I have allowed for the consumer to specify fields to be excluded, and also by default to exclude any database / model specific related properties.

    public static T Transform<T>(this object myobj, string excludeFields = null)
    {
        // Compose a list of unwanted members
        if (string.IsNullOrWhiteSpace(excludeFields))
            excludeFields = string.Empty;
        excludeFields = !string.IsNullOrEmpty(excludeFields) ? excludeFields + "," : excludeFields;
        excludeFields += $"{nameof(DBTable.ID)},{nameof(DBTable.InstanceID)},{nameof(AuditableBase.CreatedBy)},{nameof(AuditableBase.CreatedByID)},{nameof(AuditableBase.CreatedOn)}";

        var objectType = myobj.GetType();
        var targetType = typeof(T);
        var targetInstance = Activator.CreateInstance(targetType, false);

        // Find common members by name
        var sourceMembers = from source in objectType.GetMembers().ToList()
                                  where source.MemberType == MemberTypes.Property
                                  select source;
        var targetMembers = from source in targetType.GetMembers().ToList()
                                  where source.MemberType == MemberTypes.Property
                                  select source;
        var commonMembers = targetMembers.Where(memberInfo => sourceMembers.Select(c => c.Name)
            .ToList().Contains(memberInfo.Name)).ToList();

        // Remove unwanted members
        commonMembers.RemoveWhere(x => x.Name.InList(excludeFields));

        foreach (var memberInfo in commonMembers)
        {
            if (!((PropertyInfo)memberInfo).CanWrite) continue;

            var targetProperty = typeof(T).GetProperty(memberInfo.Name);
            if (targetProperty == null) continue;

            var sourceProperty = myobj.GetType().GetProperty(memberInfo.Name);
            if (sourceProperty == null) continue;

            // Check source and target types are the same
            if (sourceProperty.PropertyType.Name != targetProperty.PropertyType.Name) continue;

            var value = myobj.GetType().GetProperty(memberInfo.Name)?.GetValue(myobj, null);
            if (value == null) continue;

            // Set the value
            targetProperty.SetValue(targetInstance, value, null);
        }
        return (T)targetInstance;
    }
查看更多
Evening l夕情丶
3楼-- · 2020-01-26 04:41

You can provide an explicit overload for the cast operator:

public static explicit operator maincs(sub1 val)
{
    var ret = new maincs() { a = val.a, b = val.b, c = val.c };
    return ret;
}

Another option would be to use an interface that has the a, b, and c properties and implement the interface on both of the classes. Then just have the parameter type to methoda be the interface instead of the class.

查看更多
Deceive 欺骗
4楼-- · 2020-01-26 04:44

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);
查看更多
Evening l夕情丶
5楼-- · 2020-01-26 04:47

You could change your class structure to:

public class maincs : sub1
{
   public int d; 
}

public class sub1
{
   public int a;
   public int b;
   public int c;
}

Then you could keep a list of sub1 and cast some of them to mainc.

查看更多
爷、活的狠高调
6楼-- · 2020-01-26 04:48

You have already defined the conversion, you just need to take it one step further if you would like to be able to cast. For example:

public class sub1
{
    public int a;
    public int b;
    public int c;

    public static explicit operator maincs(sub1 obj)
    {
        maincs output = new maincs() { a = obj.a, b = obj.b, c = obj.c };
        return output;
    }
}

Which then allows you to do something like

static void Main()
{
    sub1 mySub = new sub1();
    maincs myMain = (maincs)mySub;
}
查看更多
该账号已被封号
7楼-- · 2020-01-26 04:52
var obj =  _account.Retrieve(Email, hash);

AccountInfoResponse accountInfoResponse = new AccountInfoResponse();

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

image description

查看更多
登录 后发表回答