我正在尝试为Xamarin的iOS框架创建绑定,并且它在某些NSSet属性的通用类型上tum绊绊:
// @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; }
}
产生错误
错误CS0311:类型'Namespace.Foo'不能用作通用类型或方法'NSSet'中的类型参数'TKey'。没有从'Namespace.Foo'到'ObjCRuntime.INativeObject'的隐式引用转换。
我不理解该错误,因为Foo
类基于NSObject,为什么会产生此错误?
答案 0 :(得分:1)
Foundation.NSSet<TKey> Class
被声明为
[Foundation.Register("NSSet", SkipRegistration=true)]
public sealed class NSSet<TKey> : NSSet, IEnumerable<TKey>
where TKey : class, INativeObject
也就是说,您的具体TKey
必须实现INativeObject
。 Foo
没有。如果您将Foo
更改为
interface Foo : INativeObject
{ }
...编译器错误消失。
where TKey : class, INativeObject
是(generic) Type Parameter Constraint。它告诉您TKey
的type参数必须是通过class
关键字的引用类型,并且它必须实现接口INativeObject
。
答案 1 :(得分:0)
NSSet<TKey>
定义为:
public sealed class NSSet<TKey> : NSSet, IEnumerable<TKey>
where TKey : class, INativeObject
由于Foo不满足一般约束,因此提供了iOS本机类型。
您至少可以使用 NSSet<NSObject>
,或者如果您知道将要使用的实际集合类型(或者如果需要创建辅助属性/方法),则使用最精致的对象输入您可以NSSet<NSString>
,NSSet<CGRect>
等...