Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot use class in NSSet<TKey>

Tags:

c#

ios

xamarin

I'm attempting to create a binding for an iOS Framework for Xamarin and it's stumbling on the generic type for some NSSet properties:

// @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; }
}

Produces the error

Error CS0311: The type 'Namespace.Foo' cannot be used as type parameter 'TKey' in the generic type or method 'NSSet'. There is no implicit reference conversion from 'Namespace.Foo' to 'ObjCRuntime.INativeObject'.

I don't understand the error because the Foo class is based on NSObject, why is this error being produced?

like image 249
Nick Avatar asked Nov 05 '25 06:11

Nick


1 Answers

The Foundation.NSSet<TKey> Class is declared as

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

I.e., your concrete TKey must be a class implementing INativeObject. Foo does not. If you change Foo to

interface Foo : INativeObject
{ }

... the compiler error disappears.


where TKey : class, INativeObject is a (generic) Type Parameter Constraint. It tells you that the type argument for TKey must be a reference type through the class keyword and that it must implement the interface INativeObject.

like image 153
Olivier Jacot-Descombes Avatar answered Nov 07 '25 20:11

Olivier Jacot-Descombes



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!