假设我有一个C#Nullable DateTime?
属性需要由VBA通过COM使用。
public DateTime? TestDate {
get ; set;
}
不幸的是,通过COM看不到Nullables,所以我希望该属性返回一个可以从VBA看作Variant的东西。
不幸的是,我不确定应该怎么写。
我尝试使用object
和dynamic
代替DateTime?
:虽然我可以获取属性值,但我无法设置它(我得到运行时错误'424'需要对象来自VBA的错误。)
注意:我没有让我的库COM可见的问题:一切正常,我可以毫无问题地使用VBA中的.Net类型,除了这个特殊问题。< / p>
感谢您的任何指示。
编辑:我找到了一个描述default marshalling for objects的有趣页面,但我似乎无法解释为什么如果它被声明为object
我无法设置我的属性。
我错过了什么。
答案 0 :(得分:8)
我在这里解决了这个问题。
public object MyObject {
get ; set;
}
在VBA中使用.Net Object
属性时,读取属性没有问题,它将被正确地视为Variant
。
不幸的是,尝试从VBA设置属性将失败。
但是,使用普通方法可以正常工作:
private object _MyObject;
public object GetMyObject() {
return _MyObject;
}
public void SetMyObject(object value) {
if (value == DbNull.Value)
value = null;
_MyObject = value;
}
检查DBNull
是为了解决VBA'Null
实际编组为DBNull
到.Net的问题。
现在,为了使DateTime?
可以工作,我们可以做类似的事情:
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#类将MyDate
作为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
答案 1 :(得分:0)
使用Nullable功能创建您自己的NullableDateTime
课程,例如HasValue
和Value
属性以及GetValueOrDefault
方法。