Wrzuć klasę do innej klasy lub przekonwertuj klasę do innej

Moje pytanie znajduje się w tym kodzie

Mam taką klasę

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;    
}
Author: Dor Cohen, 2010-09-09

8 answers

To co chce powiedzieć to:

"Jeśli masz dwie klasy, które mają większość tych samych właściwości, możesz rzucić obiekt z klasy a do klasy b i automatycznie sprawić, że system zrozumie przypisanie poprzez wspólne nazwy właściwości?"

Opcja 1: użyj odbicia

Wada: spowolni cię bardziej niż myślisz.

Opcja 2: niech jedna klasa wywoła się z drugiej, pierwsza z właściwościami wspólnymi, a druga z rozszerzeniem to.

Wada: Sprzężona! jeśli robisz to dla dwóch warstw w aplikacji, to dwie warstwy zostaną połączone!

Niech będzie:

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

Oto rozszerzenie dla typu obiektu:

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

Teraz używasz go tak:

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

Metoda cast sprawdza wspólne właściwości pomiędzy dwoma obiektami i wykonuje przypisanie automatycznie.

 26
Author: Stacker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-22 15:34:11

Zdefiniowałeś już konwersję, musisz tylko pójść o krok dalej, jeśli chcesz móc rzucać. Na przykład:

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

Który następnie pozwala na wykonanie czegoś takiego jak

static void Main()
{
    sub1 mySub = new sub1();
    maincs myMain = (maincs)mySub;
}
 48
Author: Anthony Pegram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-08 23:48:56

Użyj serializacji JSON i deserializacji:

using Newtonsoft.Json;

Class1 obj1 = new Class1();
Class2 obj2 = JsonConvert.DeserializeObject<Class2>(JsonConvert.SerializeObject(obj1));

Lub:

public class Class1
{
    public static explicit operator Class2(Class1 obj)
    {
        return JsonConvert.DeserializeObject<Class2>(JsonConvert.SerializeObject(obj));
    }
}

Który następnie pozwala na wykonanie czegoś takiego jak

static void Main()
{
    Class1 obj1 = new Class1();
    Class2 obj2 = (Class2)obj1;
}
 18
Author: Tyler Long,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-09 12:58:04

Możesz zmienić strukturę swojej klasy na:

public class maincs : sub1
{
   public int d; 
}

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

Następnie możesz zachować listę sub1 i wrzucić niektóre z nich do mainc.

 5
Author: Jake Pearson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-09 02:04:31

Można podać wyraźne przeciążenie dla operatora cast:

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

Inną opcją byłoby użycie interfejsu, który ma właściwości a, b I c i zaimplementowanie interfejsu na obu klasach. Następnie wystarczy, że parametr type to methoda będzie interfejsem zamiast klasy.

 2
Author: Chris Shaffer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-08 23:50:30

Za pomocą poniższego kodu można skopiować dowolny obiekt klasy do innego obiektu klasy o tej samej nazwie i tym samym typie właściwości.

public class CopyClass
{
    /// <summary>
    /// Copy an object to destination object, only matching fields will be copied
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="sourceObject">An object with matching fields of the destination object</param>
    /// <param name="destObject">Destination object, must already be created</param>
    public static void CopyObject<T>(object sourceObject, ref T destObject)
    {
        //  If either the source, or destination is null, return
        if (sourceObject == null || destObject == null)
            return;

        //  Get the type of each object
        Type sourceType = sourceObject.GetType();
        Type targetType = destObject.GetType();

        //  Loop through the source properties
        foreach (PropertyInfo p in sourceType.GetProperties())
        {
            //  Get the matching property in the destination object
            PropertyInfo targetObj = targetType.GetProperty(p.Name);
            //  If there is none, skip
            if (targetObj == null)
                continue;

            //  Set the value in the destination
            targetObj.SetValue(destObject, p.GetValue(sourceObject, null), null);
        }
    }
}

Metoda Wywołania Jak,

ClassA objA = new ClassA();
ClassB objB = new ClassB();

CopyClass.CopyObject(objOfferMast, ref objB);

Skopiuje objA do objB.

 1
Author: Kailas Mane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-16 04:59:45

Jest tu kilka świetnych odpowiedzi, chciałem tylko dodać trochę sprawdzania typu, ponieważ nie możemy założyć, że jeśli właściwości istnieją o tej samej nazwie, to są tego samego typu. Oto moja oferta, która rozciąga się na poprzedniej, bardzo doskonała odpowiedź, ponieważ miałem kilka małych usterek z nim.

W tej wersji pozwoliłem konsumentowi określić pola, które mają być wykluczone, a także domyślnie wykluczyć wszelkie powiązane właściwości bazodanowe / modelowe.

    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;
    }
 1
Author: SpaceKat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-04 22:42:44

Za pomocą tego kodu można skopiować dowolny obiekt klasy do innego obiektu klasy o tej samej nazwie i tym samym typie właściwości.

JavaScriptSerializer JsonConvert = new JavaScriptSerializer(); 
string serializeString = JsonConvert.Serialize(objectEntity);
objectViewModel objVM = JsonConvert.Deserialize<objectViewModel>(serializeString);
 1
Author: Yats_Bhavsar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-20 10:59:29