【发布时间】:2011-03-31 12:35:32
【问题描述】:
我在不同的命名空间中有两个相似的[所有属性都相同。]结构。
现在,当我尝试在这些结构的对象之间复制值时,我遇到了错误。
如何在位于不同命名空间的两个相似结构的对象之间复制值?
提前致谢。
问候,
约翰
【问题讨论】:
-
您能举例说明您想要做什么以及为什么它不起作用吗?这不是很多信息...
标签: c# .net namespaces
我在不同的命名空间中有两个相似的[所有属性都相同。]结构。
现在,当我尝试在这些结构的对象之间复制值时,我遇到了错误。
如何在位于不同命名空间的两个相似结构的对象之间复制值?
提前致谢。
问候,
约翰
【问题讨论】:
标签: c# .net namespaces
您不能自动只使用框架的内置转换。
短名称(即在命名空间内)在这里完全不相关 - 就 CLR 而言,A.B.C.SomeType 和 A.B.C1.SomeType 与 X.Y.Foo 和 A.B.Bar 一样不同。
您应该编写自己的转换例程,或者(最好)首先避免使用两种不同的类型,如果它们做同样的事情的话。或者,您可以使用基于反射的方法来执行转换......但这仍然没有让 runtime 来执行它。
【讨论】:
使用AutoMapper。
Mapper.CreateMap<My.NS1.Structure, My.NS2.Structure>();
My.NS1.Structure struct1;
My.NS2.Structure struct2 = (My.NS2.Structure) Mapper.Map(struct1);
【讨论】:
我在通过 WCF 使用来自外部提供商的多个 Web 服务时遇到了同样的问题。有一个非常大的嵌套对象树,这对于在类之间进行映射是很痛苦的,特别是因为这棵树有几个将抽象基类作为成员的实例。由于这些类都是使用传输到 Web 服务所需的 XML 序列化属性定义的,因此我选择使用序列化程序为我进行转换。
TOutput ConvertEquivalentTypes<TInput, TOutput>(TInput structure)
where TInput : class
where TOutput : class
{
TOutput result = null;
using (Stream data = new MemoryStream())
{
new XmlSerializer(typeof(TInput)).Serialize(data, structure);
data.Seek(0, SeekOrigin.Begin);
result = (TOutput)new XmlSerializer(typeof(TOutput)).Deserialize(data);
}
return result;
}
【讨论】:
That Chuck Guy 的答案的替代方案 - 您可以使用反射来获取和设置值。不知道性能的好处/坏处是什么。
public static class EquivelantStructureConversion<TInput, TOutput>
where TInput : class
where TOutput : new()
{
public static TOutput Convert(TInput input)
{
var output = new TOutput();
foreach (var inputProperty in input.GetType().GetProperties())
{
var outputProperty = output.GetType().GetProperty(inputProperty.Name);
if (outputProperty != null)
{
var inputValue = inputProperty.GetValue(input, null);
outputProperty.SetValue(output, inputValue, null);
}
}
return output;
}
}
如果输出类型的属性不存在,上面的例子不会抛出异常,但是你可以很容易地添加它。
【讨论】:
从问题中的描述看来,您希望在您的类型之间使用 implicit conversion。虽然您可能能够做到这一点,除了其他建议之外,您可能会更好地使用其他方法,例如
【讨论】:
由于所有属性都相同,您可以例如定义一个接口,描述你的结构并在你的结构中实现这个接口。 然后将您的结构转换为接口以复制值。
问候, 哦
【讨论】:
你可以使用联合:
public struct A
{
int x, y;
double a, b;
public A(int x, int y, double a, double b)
{
this.x = x;
this.y = y;
this.a = a;
this.b = b;
}
}
public struct B
{
int x, y;
double a, b;
}
[StructLayout(LayoutKind.Explicit)]
public class Union
{
[FieldOffset(0)]
public A a;
[FieldOffset(0)]
public B b;
public Union(A a)
{
this.b = default(B);
this.a = a;
}
}
class Program
{
static void Main(string[] args)
{
A a = new A(5, 10, 0.25, 0.75);
Union union = new Union(a);
B b = union.b; //contains 5,10,0.25,0.75
}
}
【讨论】: