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

发布于 2024-10-27 20:08:06 字数 151 浏览 2 评论 0原文

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

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

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

提前致谢。

问候,

约翰

I have two similar[all attributes are same.] structures within different namespaces.

Now when i try to copy values between the objects of these structures i am getting errors.

How can i make it possible to copy values between objects of two similar structures residing in different namespaces?

Thanks in advance.

Regards,

John

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

太阳男子 2024-11-03 20:08:06

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

短名称(即在命名空间内)在这里完全不相关 - 就 CLR 而言,ABCSomeTypeABC1.SomeTypeXYFoo< 一样不同。 /code> 和 ABBar

您应该编写自己的转换例程,或者(最好)首先避免使用两种不同的类型(如果它们执行相同的操作)。或者,您可以使用基于反射的方法来执行转换...但这仍然无法让运行时执行此操作。

You can't, automatically, just using the framework's built-in conversions.

The short names (i.e. within the namespace) are entirely irrelevant here - as far as the CLR is concerned, A.B.C.SomeType and A.B.C1.SomeType are as different as X.Y.Foo and A.B.Bar.

You should either write your own conversion routines, or (preferrably) avoid having two different types in the first place, if they do the same thing. Alternatively you could use a reflection-based approach to perform the conversion... but that's still not getting the runtime to do it.

晚风撩人 2024-11-03 20:08:06

使用AutoMapper

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

Use AutoMapper.

Mapper.CreateMap<My.NS1.Structure, My.NS2.Structure>();
My.NS1.Structure struct1;
My.NS2.Structure struct2 = (My.NS2.Structure) Mapper.Map(struct1);
请叫√我孤独 2024-11-03 20:08:06

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

I ran into this same problem when consuming multiple web services from an external provider through WCF. There is a very large tree of nested objects, which is just painful for doing mapping between classes, especially since this tree has several instances of holding an abstract base class as a member. Since these classes are all defined with the XML serialization attributes needed to transmit to a web service, I opted to use the serializer to do the conversion for me.

    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;
    }
笛声青案梦长安 2024-11-03 20:08:06

那查克盖伊的答案的替代方案 - 您可以使用反射来获取和设置值。不知道性能的好处/坏处是什么。

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

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

An alternative to That Chuck Guy's answer - you could use reflection to get and set the values. No idea what the performance benefits/detriments are.

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

The above example will not throw an exception if the property on the output type doesn't exist, but you could easily add it.

永不分离 2024-11-03 20:08:06

从问题的描述来看,您似乎想要隐式转换在你的类型之间。虽然您可能能够做到这一点,但除了其他建议之外,您可能最好使用其他方法,例如

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

From the description in the question it sounds like you want to have implicit conversion between your types. Whilst you may be able to do this, and in addition to the other suggestions, you might be better using other methods like

  • having a class to do the conversion for you
  • adding a constructor to each class to generate a type of A from a type of B and vice versa
  • adding an extension method to each to act as a factory for producing the other
甜味超标? 2024-11-03 20:08:06

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

问候,

as all attributes are same, you can e.g. define an interface, describe your structure and implement this interface in your structures.
Then cast your structures to the interface to copy values.

regards,
O

鸩远一方 2024-11-03 20:08:06

您可以使用联合:

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

You can use a union:

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
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文