Вот что я сделал, чтобы обойти проблему.
Свойства объекта
public object MyObject {
get ; set;
}
При использовании свойства .Net Object
из VBA чтение свойства не является проблемой, и этобудет правильно рассматриваться как 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?
Теперь, чтобы сделать nullable 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
в качестве основыstore:
[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