在 Xamarin 中绑定多维数组
Binding multi-dimentional arrays in Xamarin
我正在尝试绑定一个 属性,我知道它是一个(多维)NSArray
持有 NSArray
个对象,而这些对象又持有 [=15= 的实例].我已经绑定了这样的方法:
[Export ("options")]
NSObject[][] Options { get; set; }
当我构建我的绑定时,我在为上述 属性 生成的 class 中收到以下错误。
来自对 NSArray.FromNSObjects
的生成调用:
(1) Argument `#1` cannot convert 'Foundation.NSObject[][]' expression to type 'Foundation.NSObject[]'.
(2) Error CS1502: The best overloaded method match for `Foundation.NSArray.FromNSObjects(params Foundation.NSObject[])' has some invalid arguments (CS1502)
来自对 NSArray.ArrayFromHandle<Foundation.NSObject[]>
的生成调用:
(1) Error CS0311: The type `Foundation.NSObject[]' cannot be used as type parameter `T' in the generic type or method `Foundation.NSArray.ArrayFromHandle<T>(System.IntPtr)'. There is no implicit reference conversion from `Foundation.NSObject[]' to `ObjCRuntime.INativeObject' (CS0311)
错误一直指的是编译器无法在 Foundation.NSObject[][]
和 Foundation.NSObject[]
之间进行转换。我不明白为什么这会是个问题,NSArray
是 NSObject
的子 class,那么为什么它不能将第二个数组维度视为 NSObject
?
(我知道我有其他选择,例如将选项绑定为 NSObject[]
,或者只是 NSObject
,但我宁愿尽可能保证类型安全。)
我认为出现这个问题是因为FromNSObjects
和ArrayFromHandle
方法无法处理多维数组的转换,但我不完全确定。
我设法通过从我的绑定文件 (ApiDefinition.cs) 中删除 Options
的绑定并在部分 class 中手动绑定 属性 来解决这个问题.
我写了两个方法在多维 NSArray
和 NSObject[][]
之间转换。
private NSArray NSArraysFromTwoDimentionalArray(NSObject[][] firstDimension) {
NSMutableArray nsFirstDimension = new NSMutableArray ();
foreach (NSObject[] secondDimention in firstDimension) {
NSMutableArray nsSecondDimension = new NSMutableArray ();
foreach (NSObject nsObj in secondDimention) {
nsSecondDimension.Add (nsObj);
}
nsFirstDimension.Add (nsSecondDimension);
}
NSArray toReturn = (NSArray)nsFirstDimension.Copy ();
nsFirstDimension.Dispose ();
return toReturn;
}
private NSObject[][] TwoDimentionalArrayFromArrayOfNSArrays (NSArray[] nsFirstDimension) {
NSObject[][] firstDimension = new NSObject[nsFirstDimension.Length][];
int i = 0;
foreach (NSArray nsSecondDimension in nsFirstDimension) {
NSObject[] secondDimension = NSArray.ArrayFromHandle<NSObject> (nsSecondDimension.Handle);
firstDimension[i] = secondDimension;
i++;
}
return firstDimension;
}
然后我使用上面的转换方法来实现我的绑定。
public virtual NSObject[][] Options {
[Export ("options")]
get {
NSArray[] firstDimension;
if (IsDirectBinding) {
firstDimension = NSArray.ArrayFromHandle<NSArray> (ApiDefinition.Messaging.IntPtr_objc_msgSend (this.Handle, Selector.GetHandle ("options")));
} else {
firstDimension = NSArray.ArrayFromHandle<NSArray> (ApiDefinition.Messaging.IntPtr_objc_msgSendSuper (this.SuperHandle, Selector.GetHandle ("options")));
}
return TwoDimentionalArrayFromArrayOfNSArrays (firstDimension);
}
[Export ("setOptions:")]
set {
if (value == null)
throw new ArgumentNullException ("value");
var multiNSArray = NSArraysFromTwoDimentionalArray (value);
if (IsDirectBinding) {
ApiDefinition.Messaging.void_objc_msgSend_IntPtr (this.Handle, Selector.GetHandle ("setOptions:"), multiNSArray.Handle);
} else {
ApiDefinition.Messaging.void_objc_msgSendSuper_IntPtr (this.SuperHandle, Selector.GetHandle ("setOptions:"), multiNSArray.Handle);
}
multiNSArray.Dispose ();
}
}
我正在尝试绑定一个 属性,我知道它是一个(多维)NSArray
持有 NSArray
个对象,而这些对象又持有 [=15= 的实例].我已经绑定了这样的方法:
[Export ("options")]
NSObject[][] Options { get; set; }
当我构建我的绑定时,我在为上述 属性 生成的 class 中收到以下错误。
来自对 NSArray.FromNSObjects
的生成调用:
(1) Argument `#1` cannot convert 'Foundation.NSObject[][]' expression to type 'Foundation.NSObject[]'.
(2) Error CS1502: The best overloaded method match for `Foundation.NSArray.FromNSObjects(params Foundation.NSObject[])' has some invalid arguments (CS1502)
来自对 NSArray.ArrayFromHandle<Foundation.NSObject[]>
的生成调用:
(1) Error CS0311: The type `Foundation.NSObject[]' cannot be used as type parameter `T' in the generic type or method `Foundation.NSArray.ArrayFromHandle<T>(System.IntPtr)'. There is no implicit reference conversion from `Foundation.NSObject[]' to `ObjCRuntime.INativeObject' (CS0311)
错误一直指的是编译器无法在 Foundation.NSObject[][]
和 Foundation.NSObject[]
之间进行转换。我不明白为什么这会是个问题,NSArray
是 NSObject
的子 class,那么为什么它不能将第二个数组维度视为 NSObject
?
(我知道我有其他选择,例如将选项绑定为 NSObject[]
,或者只是 NSObject
,但我宁愿尽可能保证类型安全。)
我认为出现这个问题是因为FromNSObjects
和ArrayFromHandle
方法无法处理多维数组的转换,但我不完全确定。
我设法通过从我的绑定文件 (ApiDefinition.cs) 中删除 Options
的绑定并在部分 class 中手动绑定 属性 来解决这个问题.
我写了两个方法在多维 NSArray
和 NSObject[][]
之间转换。
private NSArray NSArraysFromTwoDimentionalArray(NSObject[][] firstDimension) {
NSMutableArray nsFirstDimension = new NSMutableArray ();
foreach (NSObject[] secondDimention in firstDimension) {
NSMutableArray nsSecondDimension = new NSMutableArray ();
foreach (NSObject nsObj in secondDimention) {
nsSecondDimension.Add (nsObj);
}
nsFirstDimension.Add (nsSecondDimension);
}
NSArray toReturn = (NSArray)nsFirstDimension.Copy ();
nsFirstDimension.Dispose ();
return toReturn;
}
private NSObject[][] TwoDimentionalArrayFromArrayOfNSArrays (NSArray[] nsFirstDimension) {
NSObject[][] firstDimension = new NSObject[nsFirstDimension.Length][];
int i = 0;
foreach (NSArray nsSecondDimension in nsFirstDimension) {
NSObject[] secondDimension = NSArray.ArrayFromHandle<NSObject> (nsSecondDimension.Handle);
firstDimension[i] = secondDimension;
i++;
}
return firstDimension;
}
然后我使用上面的转换方法来实现我的绑定。
public virtual NSObject[][] Options {
[Export ("options")]
get {
NSArray[] firstDimension;
if (IsDirectBinding) {
firstDimension = NSArray.ArrayFromHandle<NSArray> (ApiDefinition.Messaging.IntPtr_objc_msgSend (this.Handle, Selector.GetHandle ("options")));
} else {
firstDimension = NSArray.ArrayFromHandle<NSArray> (ApiDefinition.Messaging.IntPtr_objc_msgSendSuper (this.SuperHandle, Selector.GetHandle ("options")));
}
return TwoDimentionalArrayFromArrayOfNSArrays (firstDimension);
}
[Export ("setOptions:")]
set {
if (value == null)
throw new ArgumentNullException ("value");
var multiNSArray = NSArraysFromTwoDimentionalArray (value);
if (IsDirectBinding) {
ApiDefinition.Messaging.void_objc_msgSend_IntPtr (this.Handle, Selector.GetHandle ("setOptions:"), multiNSArray.Handle);
} else {
ApiDefinition.Messaging.void_objc_msgSendSuper_IntPtr (this.SuperHandle, Selector.GetHandle ("setOptions:"), multiNSArray.Handle);
}
multiNSArray.Dispose ();
}
}