лить class в другой class или преобразовать class в другой
мой вопрос указан в этом коде
У меня такой class
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; }
- Преобразование boolean в int в Java
- Имеет ли смысл использовать «как» вместо броска, даже если нет нулевой проверки?
- Почему enums требуют явного приведения в тип int?
- неявный оператор с использованием интерфейсов
- Кастинг DataTypes с DirectCast, CType, TryCast
- Разница между литьем и использованием метода Convert.To ()
- Различия в автоматическом распаковке между Java 6 и Java 7
- Почему у нас есть reinterpret_cast на C ++, когда две цепные static_cast могут выполнять свою работу?
- Почему нельзя отличать Integer от String в java?
- ошибка: лить из 'void *' в 'int' теряет точность
- Невозможно применить к неспецифическому вложенному типу с дженериками
- Не нужно бросать результат findViewById?
- литье массив объектов в массив Integer
Он хочет сказать:
«Если у вас есть два classа, которые используют одни и те же свойства, вы можете отличить объект от classа a
до classа b
и автоматически заставить систему понимать назначение через общие имена свойств?»
Вариант 1: Использовать reflection
Недостаток: он замедлит вас, чем вы думаете.
Вариант 2: сделать один class из другого, первый с общими свойствами и другим расширением этого.
Недостаток: в сочетании! если вы сделаете это для двух слоев в своем приложении, тогда два слоя будут соединены!
Пусть будет:
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; } }
Теперь это расширение для типа объекта:
public static T Cast(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 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; }
Теперь вы используете его так:
static void Main(string[] args) { var cus = new customer(); cus.firstname = "John"; cus.age = 3; employee emp = cus.Cast(); }
Метод cast проверяет общие свойства между двумя объектами и автоматически выполняет назначение.
Вы уже определили преобразование, вам просто нужно сделать это на один шаг дальше, если вы хотите, чтобы у вас была возможность бросить. Например:
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; } }
Что затем позволяет вам делать что-то вроде
static void Main() { sub1 mySub = new sub1(); maincs myMain = (maincs)mySub; }
Используйте сериализацию JSON и десериализацию:
using Newtonsoft.Json; Class1 obj1 = new Class1(); Class2 obj2 = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(obj1));
Или:
public class Class1 { public static explicit operator Class2(Class1 obj) { return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(obj)); } }
Что затем позволяет вам делать что-то вроде
static void Main() { Class1 obj1 = new Class1(); Class2 obj2 = (Class2)obj1; }
Вы можете изменить структуру своего classа:
public class maincs : sub1 { public int d; } public class sub1 { public int a; public int b; public int c; }
Затем вы можете сохранить список sub1 и перенести некоторые из них в mainc.
Вы можете обеспечить явную перегрузку для оператора трансляции:
public static explicit operator maincs(sub1 val) { var ret = new maincs() { a = val.a, b = val.b, c = val.c }; return ret; }
Другой вариант – использовать интерфейс, который имеет свойства a, b и c и реализовать интерфейс для обоих classов. Тогда просто введите тип параметра methoda как интерфейс вместо classа.
Используя следующий код, вы можете скопировать любой объект classа в другой объект classа с тем же именем и свойствами того же типа.
public class CopyClass { /// /// Copy an object to destination object, only matching fields will be copied /// /// /// An object with matching fields of the destination object /// Destination object, must already be created public static void CopyObject(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); } } }
Метод вызова Как,
ClassA objA = new ClassA(); ClassB objB = new ClassB(); CopyClass.CopyObject(objOfferMast, ref objB);
Он скопирует objA
в objB
.
Здесь есть несколько отличных ответов, я просто хотел добавить немного проверки типа здесь, поскольку мы не можем предположить, что если свойства существуют с тем же именем, они имеют один и тот же тип. Вот мое предложение, которое распространяется на предыдущий, очень отличный ответ, поскольку у меня было несколько небольших сбоев.
В этой версии я разрешил потребителю указывать поля, которые должны быть исключены, а также по умолчанию исключать любые связанные с базой / моделью соответствующие свойства.
public static T Transform(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; }
Используя этот код, вы можете скопировать любой объект classа в другой объект classа с тем же именем и свойствами того же типа.
JavaScriptSerializer JsonConvert = new JavaScriptSerializer(); string serializeString = JsonConvert.Serialize(objectEntity); objectViewModel objVM = JsonConvert.Deserialize(serializeString);