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