Bug 17885 - warning MT4112 (generic type found by registrar) for a class with no Register attribute.
Summary: warning MT4112 (generic type found by registrar) for a class with no Register...
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: 7.0.6.x
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2014-02-19 14:11 UTC by Adam Kemp
Modified: 2014-02-20 17:57 UTC (History)
2 users (show)

Is this bug a regression?: ---
Last known good build:

Example solution (7.95 KB, application/zip)
2014-02-19 14:11 UTC, Adam Kemp

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Adam Kemp 2014-02-19 14:11:08 UTC
Created attachment 6090 [details]
Example solution

The registrar is reporting warnings for classes that do not have a Register attribute. I think what's happening is that it is finding classes with a Register attribute on one of its ancestors (in this case the UIView class). I think only classes that directly have Register attributes should be given to the registrar, and so there should not be a warning reported for generic classes that inherit from UIView but don't have their own Register attribute.

Here is my understanding of which situations should and should not produce warnings:

// No warning
class A {}

// No warning
class B : A {}

// Warning
class C<T> {}

// No warning (incorrect case)
class D<T> : A {}

To reproduce open the attached solution and build one of the device (i.e., not simulator) configurations. Look in the build output for warning MT4112.
Comment 1 Rolf Bjarne Kvinge [MSFT] 2014-02-19 15:56:49 UTC
All derived classes from [Register] classes are also exported to Objective-C (in other words it's an implicit attribute once a base class has it).

This is the a feature/by design, and won't change.

We're however working on support for generic subclasses (but no timeline yet unfortunately), so class D from your sample code will eventually be a supported scenario (and no warnings/errors will be given).
Comment 2 Adam Kemp 2014-02-19 16:31:24 UTC
What exactly does it mean to be "exported to Objective-C"? My understanding was that Register was use to allow a class to be instantiated by Objective-C code, specifically for .xib files. I tested creating a view in a .xib without an explicit Register attribute, and that did not work for me. So what effect did this implicit registration have?

It does not make sense to be able to instantiate every class with a registered attribute. There are cases in which you would not want to be able to do that (for instance abstract classes, generic classes, and private classes) so I hope that this is not the goal.
Comment 3 Rolf Bjarne Kvinge [MSFT] 2014-02-20 16:25:47 UTC
"exported to Objective-C" means exactly what you think: it allows the class to be instantiated by Objective-C code. It also allows Objective-C to call methods with [Export] attributes in your class (this is the most common reason in fact).

There are no technical differences between implicit and explicit registration (the only difference is that the attribute allows you to specify the name used to export the class, if nothing is specified the full name of the class is used - which is probably why you weren't able to use an implicitly registered class from a .xib).
Comment 4 Adam Kemp 2014-02-20 16:38:38 UTC
Here are examples of classes that I don't think you should be able to instantiate in Objective-C:

abstract class A : UIView {} // You can't instantiate an abstract class

private class B : UIView {} // You shouldn't be allowed to instantiate a private class from outside its containing scope

class C<T> : UIView {} // Which type would use when instantiating this from Objective-C?

There may be others, but those seem obvious to me. That's why I don't think registration should be done implicitly just because you have an ancestor that is registered.
Comment 5 Rolf Bjarne Kvinge [MSFT] 2014-02-20 16:53:22 UTC
Instantiation isn't the only reason:

abstract class A : UIView {
    [Export ("myMethod")]
    public void MyMethod () {}

This will allow MyMethod to be called from Objective-C, using the 'myMethod' selector.
Comment 6 Adam Kemp 2014-02-20 17:02:08 UTC
Can there be a distinction between registration for the purposes of calling an exported method versus registration for the purposes of instantiation from Objective-C? The former could be based on whether NSObject is an ancestor instead of whether an ancestor has a Register attribute.
Comment 7 Rolf Bjarne Kvinge [MSFT] 2014-02-20 17:30:15 UTC
No, there can be no distinction.

When we export a managed class to Objective-C, we really create a new Objective-C class dynamically. Then to export managed methods, we add dynamically created Objective-C methods to that Objective-C class. As you can see it's necessary to have the dynamically created Objective-C class in order to be able to export managed methods as well.
Comment 8 Adam Kemp 2014-02-20 17:57:27 UTC
Ok, I'll take your word for it. You said before that you are working on allowing generics to be supported, but if that is going to be a while then maybe in the shorter term you could at least change the warning to not show up if the class being registered doesn't have any [Export] attributes (or any other related attributes that would add methods to a dynamically created Objective-C class). After all, that's the only case that really doesn't work right now, and our code doesn't actually do that. It's a spurious warning for us. Just a suggestion, though. Thanks for the explanation.