Лить класс в другой класс или преобразовать класс в другой
мой вопрос показан в этом коде
У меня такой класс
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;
}
Ответы
Ответ 1
Что он хочет сказать:
"Если у вас есть два класса, которые разделяют большинство тех же свойств, вы можете отличить объект от класса a
до класса b
и автоматически заставить систему понимать назначение через имена общих свойств?"
Вариант 1: Использовать отражение
Недостаток: он будет замедлять вас больше, чем вы думаете.
Вариант 2. Сделайте один класс из другого, первый с общими свойствами и другим расширением.
Недостаток: в сочетании! если вы сделаете это для двух слоев в своем приложении, тогда два слоя будут связаны!
Пусть будет:
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<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;
}
Теперь вы используете его следующим образом:
static void Main(string[] args)
{
var cus = new customer();
cus.firstname = "John";
cus.age = 3;
employee emp = cus.Cast<employee>();
}
Метод cast проверяет общие свойства между двумя объектами и автоматически выполняет присвоение.
Ответ 2
Вы уже определили преобразование, вам просто нужно сделать это еще на один шаг, если вы хотите, чтобы у вас была возможность бросить. Например:
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;
}
Ответ 3
Другой вариант - использовать сериализацию и десериализацию Json:
using Newtonsoft.Json;
Class1 obj1 = new Class1();
Class2 obj2 = JsonConvert.DeserializeObject<Class2>(JsonConvert.SerializeObject(obj1));
Или:
public class Class1
{
public static explicit operator Class2(Class1 obj)
{
return JsonConvert.DeserializeObject<Class2>(JsonConvert.SerializeObject(obj));
}
}
Что затем позволяет вам сделать что-то вроде
static void Main()
{
Class1 obj1 = new Class1();
Class2 obj2 = (Class2)obj1;
}
Ответ 4
Вы можете изменить структуру своего класса на:
public class maincs : sub1
{
public int d;
}
public class sub1
{
public int a;
public int b;
public int c;
}
Затем вы можете сохранить список sub1 и перенести некоторые из них в mainc.
Ответ 5
Вы можете предоставить явную перегрузку для оператора трансляции:
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 и реализовать интерфейс для обоих классов. Тогда просто введите тип параметра methoda как интерфейс, а не класс.
Ответ 6
Используя следующий код, вы можете скопировать любой объект класса в другой объект класса с тем же именем и свойствами того же типа.
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);
}
}
}
Метод вызова Like,
ClassA objA = new ClassA();
ClassB objB = new ClassB();
CopyClass.CopyObject(objOfferMast, ref objB);
Скопирует objA
в objB
.