微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

COM Interop:我应该怎么做才能使C#属性可用作VBA中的VARIANT

如何解决COM Interop:我应该怎么做才能使C#属性可用作VBA中的VARIANT

| 假设我有一个C#Nullable
DateTime?
属性,VBA需要通过COM使用它。
    public DateTime? TestDate {
        get ; set;
    }
不幸的是,Nullables无法通过COM看到,因此我希望该属性返回某种东西,该东西将被视为VBA中的Variant。 不幸的是,我不确定该如何编写。 我尝试使用
object
dynamic
而不是
DateTime?
:虽然可以获取属性值,但无法设置它(我从VBA中获取运行时错误\'424 \'对象必需的错误)。 注意:使我的库成为COM Visible时没有任何问题:一切正常,并且可以使用VBA中的.Net类型,但没有特殊问题。 感谢您的指导。 编辑:我发现了一个有趣的页面,该页面描述了对象的认编组,但是我似乎无法解释为什么如果将属性声明为
object
,则无法设置我的属性。 我想念一些东西。     

解决方法

        在这里,我做了什么来解决这个问题。 对象属性
public object MyObject {
    get ; set;
}
使用VBA的.Net
Object
属性时,读取属性没有问题,它将被正确视为seen8ѭ。 不幸的是,尝试从VBA设置属性将失败。 但是,使用普通方法会很好地工作:
private object _MyObject;

public object GetMyObject() {
    return _MyObject;
}

public void SetMyObject(object value) {
    if (value == DbNull.Value)
        value = null;   
    _MyObject = value;
}
对ѭ10的检查是为了解决VBAѭѭ11实际上被编组为.Net的ѭ10的问题。 约会时间? 现在,要使可为空的ѭ0起作用,我们可以执行以下操作:
private DateTime? _MyDate;

public object GetMyDate() {
    return _MyDate
}

public void SetMyDate(object value) {
    if (value == null || value == DbNull.Value)
        _MyDate = null;   
    else
        _MyDate = (DateTime?)value;
}
在VBA中,我们可以将这些get / set隐藏在属性中(假设在
myclassinstance
中有我们类的现有实例):   
Public Property Get MyDate() As Variant
    MyDate = myclassinstance.GetMyDate()
End Property

Public Property Set MyDate(value as Variant)
    myclassinstance.SetMyDate value
End Property
更通用的方式 这有点丑陋,因为我们的C#类将ѭ17暴露为GetMyDate / SetMyDate方法而不是属性。 为了以更通用的方式实现此功能,以便该机制可用于我们类中的所有属性,我们可以使用
Dictionary
作为后备存储:
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class MyClass {

    private Dictionary<string,object> backingStore = new Dictionary<string,object>();

    public object GetPropertyValue(string propertyName) {
        if (backingStore.ContainsKey(propertyName))
            return backingStore[propertyName];
        else
            return null
    }

    public void SetPropertyValue(string propertyName,object value) {
        if (value == DBNull.Value) value = null;
        if (backingStore.ContainsKey(propertyName))
            backingStore[propertyName] = value;
        else
            backingStore.Add(propertyName,value);
    }

    [ComVisible(false)]
    public DateTime? MyDate {
        get {
            return GetPropertyValue(@\"MyDate\") ?? default(DateTime?);
        }
        set {
            SetPropertyValue(@\"MyDate\",value);
        }            
    }
}
ComVisible(false)
属性确保该属性在VBA中不可见。 在VBA中,我们声明属性:
Public Property Get MyDate() As Variant
    MyDate = myclassinstance.GetPropertyValue(\"MyDate\")
End Property

Public Property Set MyDate(value as Variant)
    myclassinstance.SetPropertyValue \"MyDate\",value
End Property
    ,        使用Nullable功能(例如
HasValue
Value
属性以及
GetValueOrDefault
方法)创建自己的
NullableDateTime
类。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。