【问题标题】:Converting values between same structure within different namespace. C#在不同命名空间内的相同结构之间转换值。 C#
【发布时间】:2011-03-31 12:35:32
【问题描述】:

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

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

如何在位于不同命名空间的两个相似结构的对象之间复制值?

提前致谢。

问候,

约翰

【问题讨论】:

  • 您能举例说明您想要做什么以及为什么它不起作用吗?这不是很多信息...

标签: c# .net namespaces


【解决方案1】:

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

短名称(即在命名空间内)在这里完全不相关 - 就 CLR 而言,A.B.C.SomeTypeA.B.C1.SomeTypeX.Y.FooA.B.Bar 一样不同。

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

【讨论】:

    【解决方案2】:

    使用AutoMapper

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        如果输出类型的属性不存在,上面的例子不会抛出异常,但是你可以很容易地添加它。

        【讨论】:

          【解决方案5】:

          从问题中的描述看来,您希望在您的类型之间使用 implicit conversion。虽然您可能能够做到这一点,除了其他建议之外,您可能会更好地使用其他方法,例如

          • 有一个类为您进行转换
          • 为每个类添加一个构造函数以从 B 类型生成 A 类型,反之亦然
          • 为每个添加扩展方法以充当生产另一个的工厂

          【讨论】:

            【解决方案6】:

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

            问候, 哦

            【讨论】:

              【解决方案7】:

              你可以使用联合:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2021-07-17
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-07-31
                • 2015-05-06
                相关资源
                最近更新 更多