无法在NSSet <tkey>

时间:2018-10-05 13:18:31

标签: c# ios xamarin

我正在尝试为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,为什么会产生此错误?

2 个答案:

答案 0 :(得分:1)

Foundation.NSSet<TKey> Class被声明为

[Foundation.Register("NSSet", SkipRegistration=true)]
public sealed class NSSet<TKey> : NSSet, IEnumerable<TKey>
    where TKey : class, INativeObject

也就是说,您的具体TKey必须实现INativeObjectFoo没有。如果您将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

re:https://github.com/xamarin/xamarin-macios/blob/bc492585d137d8c3d3a2ffc827db3cdaae3cc869/src/Foundation/NSSet_1.cs#L37

由于Foo不满足一般约束,因此提供了iOS本机类型。

您至少可以使用 NSSet<NSObject> ,或者如果您知道将要使用的实际集合类型(或者如果需要创建辅助属性/方法),则使用最精致的对象输入您可以NSSet<NSString>NSSet<CGRect>等...