【问题标题】:c# Convert struct to another struct时间:2019-01-10 标签:c#convert struct to another struct
【发布时间】:2022-02-09 20:00:45
【问题描述】:

有什么办法,如何转换:

namespace Library
{
    public struct Content
    {
        int a;
        int b;
    }
}

我在 Library2.Content 中有结构,其数据定义方式相同 ({ int a; int b; }),但方法不同。

有没有办法将结构实例从 Library.Content 转换为 Library2.Content?比如:

Library.Content c1 = new Library.Content(10, 11);
Library2.Content c2 = (Libary2.Content)(c1); //this doesn't work

【问题讨论】:

    标签: c# struct


    【解决方案1】:

    您有多种选择,包括:

    • 您可以定义从一种类型到另一种类型的显式(或隐式)转换运算符。请注意,这意味着一个库(定义转换运算符的库)必须依赖于另一个库。
    • 您可以定义自己的实用程序方法(可能是扩展方法),将任何一种类型转换为另一种。在这种情况下,您进行转换的代码需要更改为调用实用程序方法,而不是执行强制转换。
    • 您可以新建一个Library2.Content 并将Library.Content 的值传递给构造函数。

    【讨论】:

    • 如果因为无法访问构造函数或其他某些类型而无法访问怎么办?这是我创建单元测试所需的东西,但遗憾的是库不允许我创建自己的 scruct 实例。
    【解决方案2】:

    为了完整起见,如果数据类型的布局相同,还有另一种方法可以做到这一点 - 通过编组。

    static void Main(string[] args)
    {
    
        foo1 s1 = new foo1();
        foo2 s2 = new foo2();
        s1.a = 1;
        s1.b = 2;
    
        s2.c = 3;
        s2.d = 4;
    
        object s3 = s1;
        s2 = CopyStruct<foo2>(ref s3);
    
    }
    
    static T CopyStruct<T>(ref object s1)
    {
        GCHandle handle = GCHandle.Alloc(s1, GCHandleType.Pinned);
        T typedStruct = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
        handle.Free();
        return typedStruct;
    }
    
    struct foo1
    {
        public int a;
        public int b;
    
        public void method1() { Console.WriteLine("foo1"); }
    }
    
    struct foo2
    {
        public int c;
        public int d;
    
        public void method2() { Console.WriteLine("foo2"); }
    }
    

    【讨论】:

    • 如果你允许不安全的代码,同样的:foo2 s2 = *(foo2*)&amp;s1;
    • 哈哈,我只是想写同样的东西:)
    • @C.Evenhuis 我做不到。收到消息:无法获取托管类型的地址、大小或声明指向托管类型的指针。我的 foo2 等于 foo1,我无法访问 foo1,所以我想将我的“不安全”转换为该类型。
    • @Darkgaze 这个技巧只适用于结构,如果你使用泛型,我认为你需要一个where T : unmanaged 约束。
    • @C.Evenhuis 问题在于它包含指向类的指针。 :-/ 所以是的,这不是一个理想的情况。
    【解决方案3】:

    您可以在Library2.Content 中定义一个显式的conversion operator,如下所示:

    // explicit Library.Content to Library2.Content conversion operator
    public static explicit operator Content(Library.Content content) {
        return new Library2.Content {
           a = content.a,
           b = content.b
        };
    }
    

    【讨论】:

    • 问题是,我在 Library2 中没有访问权限,在 Library1 中我不知道 Library2 的存在
    • 然后选择@Kent Boogaart 的第二个或第三个选项。
    【解决方案4】:

    比赛有点晚了。但是如果结构匹配我过去使用过这个

    var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(targetType));
    Marshal.StructureToPtr(sourceStruct, ptr, false);
    var targetStruct = Marshal.PtrToStructure(ptr, targetType);
    

    【讨论】:

    • 我认为你需要释放 AllocHGlobal 分配的内存,或者你有非托管内存泄漏
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    • 2014-11-13
    • 1970-01-01
    相关资源
    最近更新 更多