wake-up-neo.net

klasse in eine andere Klasse umwandeln oder Klasse in eine andere umwandeln

meine Frage wird in diesem Code gezeigt 

Ich habe Klasse so 

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;    
}
29
Khalid Omar

Was er sagen will ist: 

"Wenn Sie über zwei Klassen verfügen, die die meisten Eigenschaften besitzen, können Sie ein Objekt von der Klasse a in die Klasse b umwandeln und das System die Zuweisung über die gemeinsamen Eigenschaftsnamen automatisch verstehen lassen."

Option 1: Reflektion verwenden 

Nachteil: Sie werden langsamer als Sie denken.

Option 2: Lassen Sie eine Klasse von einer anderen ableiten, die erste mit gemeinsamen Eigenschaften und eine andere davon.

Nachteil: Gekoppelt! Wenn Sie dies für zwei Ebenen in Ihrer Anwendung tun, werden die beiden Ebenen gekoppelt!

Lass es sein:

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

Hier nun eine Erweiterung für den Objekttyp:

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

Jetzt benutzt du es so:

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

Method Cast prüft allgemeine Eigenschaften zwischen zwei Objekten und führt die Zuweisung automatisch durch.

29
Stacker

Sie haben die Konvertierung bereits definiert. Sie müssen nur einen Schritt weitergehen, wenn Sie die Konvertierung durchführen möchten. Zum Beispiel: 

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

Was erlaubt Ihnen dann etwas zu tun 

static void Main()
{
    sub1 mySub = new sub1();
    maincs myMain = (maincs)mySub;
}
51
Anthony Pegram

Verwenden Sie JSON-Serialisierung und Deserialisierung:

using Newtonsoft.Json;

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

Oder:

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

Was erlaubt Ihnen dann etwas zu tun

static void Main()
{
    Class1 obj1 = new Class1();
    Class2 obj2 = (Class2)obj1;
}
27
Tyler Long

Sie können Ihre Klassenstruktur folgendermaßen ändern:

public class maincs : sub1
{
   public int d; 
}

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

Dann könnten Sie eine Liste von₁ führen und einige davon in mainc umwandeln.

5
Jake Pearson

Sie können den Cast-Operator explizit überladen:

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

Eine andere Option wäre die Verwendung einer Schnittstelle mit den Eigenschaften a, b und c und die Implementierung der Schnittstelle in beiden Klassen. Dann muss nur der Parametertyp die Schnittstelle anstelle der Klasse sein.

2
Chris Shaffer

Mit diesem Code können Sie jedes Klassenobjekt in ein anderes Klassenobjekt für denselben Namen und denselben Eigenschaftstyp kopieren.

JavaScriptSerializer JsonConvert = new JavaScriptSerializer(); 
string serializeString = JsonConvert.Serialize(objectEntity);
objectViewModel objVM = JsonConvert.Deserialize<objectViewModel>(serializeString);
1
Yats_Bhavsar

Mit folgendem Code können Sie jedes Klassenobjekt in ein anderes Klassenobjekt für denselben Namen und denselben Typ von Eigenschaften kopieren.

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

Aufrufmethode Wie

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

CopyClass.CopyObject(objOfferMast, ref objB);

Es wird objA in objB kopieren.

1
Kailas Mane

Hier gibt es einige großartige Antworten. Ich wollte hier nur ein wenig zur Typprüfung hinzufügen, da wir nicht davon ausgehen können, dass, wenn Eigenschaften denselben Namen haben, sie vom selben Typ sind. Hier ist mein Angebot, das sich auf die vorherige, sehr hervorragende Antwort erstreckt, da ich ein paar kleine Probleme damit hatte.

In dieser Version habe ich dem Konsumenten gestattet, die auszuschließenden Felder anzugeben, und standardmäßig, um alle datenbank-/modellspezifischen verwandten Eigenschaften auszuschließen.

    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
SpaceKat
var obj =  _account.Retrieve(Email, hash);

AccountInfoResponse accountInfoResponse = new AccountInfoResponse();

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

Bildbeschreibung