如何为 Variant 值创建类型安全的包装器

发布于 2024-08-10 08:22:17 字数 1693 浏览 3 评论 0原文

我正在使用 OPC Server 控件,该控件将数据标签存储为变体类型,由 < 描述强>System.Runtime.InteropServices.VarEnum。这些类型包括以下类型:VT_BSTR(字符串)、VT_I2(短)和 VT_I4(长)。

所有这些值都由服务器存储为对象,然后在获取它们时必须转换为正确的值。

我知道我可以执行如下操作:

object tagValue = (object)"testing"; //this would be returned from a function rather than created this way!!
var typedVariant = new TypedVariant<string>(tagValue);
string actualString = typedVariant.Value;

其中 TypedVariant 是一个通用类,如下所示:

class TypedVariant<T> where T : class, struct
{          
    public TypedVariant(object variant)
    {
        Value = variant as T;
    }

    public T Value { private set; get; }

    public static implicit operator TypedVariant<T> (T m)
    {
        // code to convert from TypedVariant<T> to T
        return new TypedVariant<T>(m);
    }

    public static implicit operator T (TypedVariant<T> m)
    {
        // code to convert from T to TypedVariant<T>
        return m.Value;
    }  
}

但是有什么方法可以在运行时完成这一切,即如下所示:

TypedVariant<> typedVariant = TypedVariant.Create(VarEnum.VT_BSTR, tagValue);
//typedVariant should now be of type TypedVariant<string>    

显然此代码不会编译,但可以可以这样做吗?

更新:根据@Konamiman的建议,我已经更改了类以允许隐式转换。因此,您现在可以编写此代码,并且它都是类型安全的,因此您不能将变体存储为与创建它所用的类型不同的类型。

object objectStr = (object)"testing"; //created this way just for testing        
TypedVariant<string> typedVariant = (string)objectStr;
string actualString = typedVariant;

I'm working with a OPC Server control that stores data tags as variant types, described by System.Runtime.InteropServices.VarEnum. These types include the following, VT_BSTR (string), VT_I2 (short) and VT_I4 (long).

All these values are stored by the server as objects and then I have to cast to the correct value when I fetch them.

I know that I can do something like the following:

object tagValue = (object)"testing"; //this would be returned from a function rather than created this way!!
var typedVariant = new TypedVariant<string>(tagValue);
string actualString = typedVariant.Value;

Where TypedVariant is a generic class something like this:

class TypedVariant<T> where T : class, struct
{          
    public TypedVariant(object variant)
    {
        Value = variant as T;
    }

    public T Value { private set; get; }

    public static implicit operator TypedVariant<T> (T m)
    {
        // code to convert from TypedVariant<T> to T
        return new TypedVariant<T>(m);
    }

    public static implicit operator T (TypedVariant<T> m)
    {
        // code to convert from T to TypedVariant<T>
        return m.Value;
    }  
}

But is there any way I can do it all at runtime, i.e. something like the following:

TypedVariant<> typedVariant = TypedVariant.Create(VarEnum.VT_BSTR, tagValue);
//typedVariant should now be of type TypedVariant<string>    

Obviously this code won't compile, but can it be done like this?

Update: as per the suggestion from @Konamiman, I've changed the class to allow implicit casting. So you can now write this code and it's all typesafe, so you can't store the variant in a different type than the one it was created with.

object objectStr = (object)"testing"; //created this way just for testing        
TypedVariant<string> typedVariant = (string)objectStr;
string actualString = typedVariant;

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

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

发布评论

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

评论(1

萌酱 2024-08-17 08:22:17

我认为 TypedVariant 包装器是一个好主意,您可以扩展它以覆盖来自/到包装类型的隐式转换运算符,然后您将能够更透明地使用它,例如:

var typedVariant = (string)tagValue;
string actualString = typedVariant;

参见此处:MSDN 上的“隐式”关键字参考

I think that the TypedVariant wrapper is a good idea, you could extend it to override the implicit conversion operator from/to the wrapped type and then you would be able to use it more transparently, such as:

var typedVariant = (string)tagValue;
string actualString = typedVariant;

See here: "implicit" keyword reference at MSDN

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