C++的VARIANT数据类型转换为C#

kam*_*mal 9 c# c++ type-conversion variant

什么相当于C#中C++的VARIANT数据类型?

我在C++中使用VARIANT数据类型的代码.如何在C#中转换该代码?

atl*_*ste 8

好吧,C++中实际上有两个变体:boost :: variant和COM变体.解决方案或多或少地遵循相同的想法,但前者更复杂.我希望你的意思是使用后者.

首先让我先告诉我,如果可能的话,这是你不应该使用的东西.那就是说,你就是这样做的:-)

变种和互操作

如果您需要字节表示相同,变量有时用于互操作.

如果您正在处理互操作,请务必查看VariantWrapperMSDN上的课程并使其正常工作.

变体和移植注意事项

变体主要用于API,通常如下所示:

void Foo(SomeEnum operation, Variant data);
Run Code Online (Sandbox Code Playgroud)

在C++中这样做的原因是因为没有基object类,因此你需要这样的东西.移植它的最简单方法是将签名更改为:

void Foo(SomeEnum operation, object data);
Run Code Online (Sandbox Code Playgroud)

但是,如果您正在移植,那么您也非常想要考虑这两个,因为它们在编译时得到解决,并且可以为您节省通常在方法中遵循的大"开关" Foo:

void SomeOperation(int data);
void SomeOperation(float data);
// etc
Run Code Online (Sandbox Code Playgroud)

变量和字节一致性

在极少数情况下,您需要自己操作字节.

本质上,变体只是一个包含在单个值类型(struct)中的值类型的大型联合.在C++中,您可以在堆上分配值类型,因为结构与类相同(排序很好).如何使用值类型只是有点重要,但稍后会更多.

Union简单地表示您将重叠内存中的所有数据.请注意我如何明确指出上面的值类型; 对于变体而言,这基本上就是它的全部内容.这也为我们提供了一种测试方法 - 即通过检查结构中的另一个值.

在C#中执行此操作的方法是StructLayout在值类型中使用该属性,其基本上如下所示:

[StructLayout(LayoutKind.Explicit)]
public struct Variant
{
    [FieldOffset(0)]
    public int Integer;
    [FieldOffset(0)]
    public float Float;
    [FieldOffset(0)]
    public double Double;
    [FieldOffset(0)]
    public byte Byte;
    // etc
}

// Check if it works - shouldn't print 0.
public class VariantTest
{
    static void Main(string[] args)
    {
        Variant v = new Variant() { Integer = 2 };
        Console.WriteLine("{0}", v.Float);

        Console.ReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

如前所述,C++变体也可以存储在堆上.如果这样做,您可能仍希望内存签名相同.这样做的方法是将我们之前构建的Variant结构框封装到其中object.


Ken*_*Kin 1

这是一个棘手的问题。

从 C# 4 开始,您可以使用动态来指示该类型在运行时已知。

然而,根据我个人的理解,c++ 需要编译时已知的类型。因此,您可能会考虑使用object, 但object在 C# 中是现有类型。

对于 VARIANT 的多类型、单值(又称多态性)概念,您不需要在 C# 中找到相应的类型,只需定义您的类和接口即可。您始终可以引用一个对象作为该类实现的接口。

如果您要移植代码,并找出可以在 LHS 中简单使用的语法,并且考虑到类型在编译时已知,那么请使用var