在不同命名空间内的相同结构之间转换值。 C#

时间:2011-03-31 12:35:33

标签: c# .net namespaces

我在不同的名称空间中有两个相似的[所有属性都相同。]结构。

现在,当我尝试在这些结构的对象之间复制值时,我遇到了错误。

如何才能在驻留在不同命名空间中的两个相似结构的对象之间复制值?

提前致谢。

此致

约翰

7 个答案:

答案 0 :(得分:5)

使用AutoMapper

Mapper.CreateMap<My.NS1.Structure, My.NS2.Structure>();
My.NS1.Structure struct1;
My.NS2.Structure struct2 = (My.NS2.Structure) Mapper.Map(struct1);

答案 1 :(得分:5)

您不能自动使用框架的内置转换。

短名称(即名称空间内)完全不相关 - 就CLR而言,A.B.C.SomeTypeA.B.C1.SomeTypeX.Y.Foo和{{1}不同}。

你应该编写自己的转换例程,或者(最好)首先避免使用两种不同的类型,如果它们做同样的事情。或者,您可以使用基于反射的方法来执行转换......但是仍然没有让运行时来执行转换。

答案 2 :(得分:5)

当通过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;
    }

答案 3 :(得分:2)

The 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;
    }
}

如果输出类型的属性不存在,上面的示例不会抛出异常,但您可以轻松添加它。

答案 4 :(得分:0)

根据问题中的描述,您可能希望在类型之间使用implicit conversion。虽然您可以这样做,除了其他建议之外,您可能更好地使用其他方法,例如

  • 有一个班级为你做转换
  • 向每个类添加构造函数以从B类型生成A类型,反之亦然
  • 为每个人添加一个扩展方法,以作为生产其他
  • 的工厂

答案 5 :(得分:0)

由于所有属性都相同,您可以例如定义一个接口,描述您的结构并在您的结构中实现此接口。 然后将结构转换为接口以复制值。

的问候, 0

答案 6 :(得分:0)

您可以使用联合:

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
    }
}