cast class into another class or convert class to another

前端 未结 9 605
逝去的感伤
逝去的感伤 2020-11-28 22:29

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


        
相关标签:
9条回答
  • 2020-11-28 23:18

    What he wants to say is:

    "If you have two classes which share most of the same properties you can cast an object from class a to class b and automatically make the system understand the assignment via the shared property names?"

    Option 1: Use reflection

    Disadvantage : It's gonna slow you down more than you think.

    Option 2: Make one class derive from another, the first one with common properties and other an extension of that.

    Disadvantage: Coupled! if your're doing that for two layers in your application then the two layers will be coupled!

    Let there be:

    class customer
    {
        public string firstname { get; set; }
        public string lastname { get; set; }
        public int age { get; set; }
    }
    class employee
    {
        public string firstname { get; set; }
        public int age { get; set; } 
    }
    

    Now here is an extension for Object type:

    public static T Cast<T>(this Object myobj)
    {
        Type objectType = myobj.GetType();
        Type target = typeof(T);
        var x = Activator.CreateInstance(target, false);
        var z = from source in objectType.GetMembers().ToList()
            where source.MemberType == MemberTypes.Property select source ;
        var d = from source in target.GetMembers().ToList()
            where source.MemberType == MemberTypes.Property select source;
        List<MemberInfo> members = d.Where(memberInfo => d.Select(c => c.Name)
           .ToList().Contains(memberInfo.Name)).ToList();
        PropertyInfo propertyInfo;
        object value;
        foreach (var memberInfo in members)
        {
            propertyInfo = typeof(T).GetProperty(memberInfo.Name);
            value = myobj.GetType().GetProperty(memberInfo.Name).GetValue(myobj,null);
    
            propertyInfo.SetValue(x,value,null);
        }   
        return (T)x;
    }  
    

    Now you use it like this:

    static void Main(string[] args)
    {
        var cus = new customer();
        cus.firstname = "John";
        cus.age = 3;
        employee emp =  cus.Cast<employee>();
    }
    

    Method cast checks common properties between two objects and does the assignment automatically.

    0 讨论(0)
  • 2020-11-28 23:19

    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;
        }
    
    0 讨论(0)
  • 2020-11-28 23:21

    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);
    
    0 讨论(0)
提交回复
热议问题