我正在尝试为 Xamarin 创建 iOS 框架的绑定,但它在某些 NSSet 属性的泛型类型上遇到了困难:
// @interface Foo : NSObject
[BaseType(typeof(NSObject))]
interface Foo
{ ... }
// @interface Bar : NSObject
[BaseType(typeof(NSObject))]
interface Bar
{
// @property (readonly, nonatomic) NSSet<Foo *> * _Nonnull foos;
[Export("foos")]
NSSet<Foo> foos { get; }
}
Run Code Online (Sandbox Code Playgroud)
产生错误
错误 CS0311:类型“Namespace.Foo”不能用作泛型类型或方法“NSSet”中的类型参数“TKey”。没有从“Namespace.Foo”到“ObjCRuntime.INativeObject”的隐式引用转换。
我不明白这个错误,因为该类Foo是基于 NSObject 的,为什么会产生这个错误?
被Foundation.NSSet<TKey> Class声明为
[Foundation.Register("NSSet", SkipRegistration=true)]
public sealed class NSSet<TKey> : NSSet, IEnumerable<TKey>
where TKey : class, INativeObject
Run Code Online (Sandbox Code Playgroud)
即,您的具体TKey必须是一个实现INativeObject. Foo才不是。如果你更改Foo为
interface Foo : INativeObject
{ }
Run Code Online (Sandbox Code Playgroud)
...编译器错误消失。
where TKey : class, INativeObject是一个(通用)类型参数约束。它通过关键字告诉您 的类型参数TKey必须是引用类型class,并且它必须实现该接口INativeObject。