假设我有两个具有相同接口的类:
interface ISomeInterface
{
int foo{get; set;}
int bar{get; set;}
}
class SomeClass : ISomeInterface {}
class SomeOtherClass : ISomeInterface {}
假设我有一个表示SomeClass的ISomeInterface实例。有没有一种简单的方法可以将其复制到SomeOtherClass的新实例中,而无需手动复制每个成员?
UPDATE:对于记录,我不尝试将SomeClass的实例强制转换为SomeOtherClass的实例。我想做的是这样的事情:
ISomeInterface sc = new SomeClass() as ISomeInterface;
SomeOtherClass soc = new SomeOtherClass();
soc.foo = sc.foo;
soc.bar = soc.bar;
我只是不想为每个人手动执行此操作,因为这些对象具有许多属性。
答案 0 :(得分:9)
您可以在每个类中创建隐式运算符来为您进行转换:
public class SomeClass
{
public static implicit operator SomeOtherClass(SomeClass sc)
{
//replace with whatever conversion logic is necessary
return new SomeOtherClass()
{
foo = sc.foo,
bar = sc.bar
}
}
public static implicit operator SomeClass(SomeOtherClass soc)
{
return new SomeClass()
{
foo = soc.foo,
bar = soc.bar
}
}
//rest of class here
}
然后SomeOtherClass soc = sc;
反之亦然。
答案 1 :(得分:6)
接口的重点不是必须这样做吗?您是否正在使用SomeOtherClass的具体实现?使用界面而不是使用具体实现,如果您使用SomeClass或SomeOther类则无关紧要。
除此之外,您可以做的最好的事情是编写某种辅助函数(您仍需要手动执行,或查看反射),复制接口上的每个属性,如下所示:
public ISomeInterface CopyValues(ISomeInterface fromSomeClass, ISomeInterface toSomeOtherClass)
{
//copy properties here
return toSomeOtherClass;
}
然而,我的第一直觉是说要远离实施并使用你的界面集中精力,那么下面的内容并不重要。
答案 2 :(得分:4)
Reflection ...遍历每个属性,并将其设置在另一个对象的相应属性上。
答案 3 :(得分:4)
查看Joe对Reflection解决方案的回答。
我假设您使用的是Visual Studio。
你熟悉ctrl + shift + r和ctrl + shift + p快捷键吗? 如果没有,ctrl + shift + r开始/结束录制击键宏。 ctrl + shift + p播放录制的宏。
当我设置了很多属性时,我所做的就是将属性声明复制到我希望它们被设置的位置,并记录一个宏,用于将声明变为set语句并将光标移动到下一行,然后我只是播放它,直到我完成所有设置语句。
答案 4 :(得分:3)
不,为了将对象从一种类型透明地转换(强制转换)到另一种类型,您拥有的对象的基础具体类必须从您尝试将其强制转换为的类继承,即使它们都是相同的接口
想一想,所有两个对象必须具有共同点,才能实现相同的接口,是方法签名的相同子集。他们可能没有(可能没有)甚至具有相同的属性或数据字段。答案 5 :(得分:3)
这不会起作用吗?
class MyClass : ICloneable
{
public MyClass()
{
}
public object Clone() // ICloneable implementation
{
MyClass mc = this.MemberwiseClone() as MyClass;
return mc;
}
你只需要调用:MyClass.Clone()。
答案 6 :(得分:3)
“你能给我一个如何做到这一点的例子(或者至少指出我正确使用的方法)吗?我似乎无法在MSDN上找到它们” - 杰森贝克
杰森,如下所示:var props = typeof(Foo)
.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo p in props)
{
// p.Name gives name of property
}
我建议编写一个工具来拼出复制构造函数所需的代码,而不是在运行时反思地执行它 - 这样性能会降低。
答案 7 :(得分:3)
ISomeInterface sc = new SomeClass() as ISomeInterface;
SomeOtherClass soc = new SomeOtherClass();
foreach (PropertyInfo info in typeof(ISomeInterface)
.GetProperties(BindingFlags.Instance
|BindingFlags.Public))
{
info.SetValue(soc,info.GetValue(sc,null),null);
}
答案 8 :(得分:2)
我确实喜欢以下内容,它非常适合使用隐式运算符从一个对象转换为另一个对象:
class Program { static void Main(string[] args) { Console.WriteLine("hello"); ExecutionReport er = new ExecutionReport("ORDID1234",3000.43,DateTime.UtcNow); Order ord = new Order(); ord = er; Console.WriteLine("Transferred values are : " + er.OrderId + "\t" + ord.Amount.ToString() + "\t" + ord.TimeStamp.ToString() + "\t"); Console.ReadLine(); } } public class Order { public string OrderId { get; set; } public double Amount { get; set; } public DateTime TimeStamp { get; set; } public static implicit operator ExecutionReport(Order ord) { return new ExecutionReport() { OrderId = ord.OrderId, Amount = ord.Amount, TimeStamp = ord.TimeStamp }; } public static implicit operator Order(ExecutionReport er) { return new Order() { OrderId = er.OrderId, Amount = er.Amount, TimeStamp = er.TimeStamp }; } public Order() { } } public class ExecutionReport { public string OrderId { get; set; } public double Amount { get; set; } public DateTime TimeStamp { get; set; } public ExecutionReport() { } public ExecutionReport(string orderId,double amount, DateTime ts) { OrderId = orderId; Amount = amount; TimeStamp = ts; } }