Is it possible to export a renderer for a generic view?

SeanMattoxSeanMattox ✭✭USMember ✭✭

My question is relatively simple. I have a renderer, which at the moment I am exporting like so:

[assembly: ExportRenderer(typeof(BindablePicker), typeof(BindablePickerRenderer))]
[assembly: ExportRenderer(typeof(BindablePicker), typeof(BindablePickerRenderer))]
[assembly: ExportRenderer(typeof(BindablePicker), typeof(BindablePickerRenderer))]

It works fine, except for being hidiously cumbersome and completly unnecessarily having to reference every single picker instance we using. Removing the explicit type arguments to reference just the generic BindablePicker class looks like this:

[assembly: ExportRenderer(typeof(BindablePicker<>), typeof(BindablePickerRenderer))]

This, however, does not work; none of the pickers now get picked up by the BindablePickerRenderer.

Is there any way to make this work? If not, there really should be.

Posts

  • adamkempadamkemp mod USInsider, Developer Group Leader mod

    I think some of your code got mangled. Try indenting it all by four spaces so that it gets formatted as code.

  • SeanMattoxSeanMattox ✭✭ USMember ✭✭

    Too late to edit now unfortunately. :( I see what you mean though. Let me try that again:

    Working but really ugly:

    [assembly: ExportRenderer(typeof(BindablePicker<ClassX>), typeof(BindablePickerRenderer))]
    [assembly: ExportRenderer(typeof(BindablePicker<ClassY>), typeof(BindablePickerRenderer))]
    [assembly: ExportRenderer(typeof(BindablePicker<ClassZ>), typeof(BindablePickerRenderer))]
    

    What I'd like to do:

    [assembly: ExportRenderer(typeof(BindablePicker<>), typeof(BindablePickerRenderer))]
    

    Just using the generic type seems vastly more intuitive than having to export every single version of the view, but I'm concerned Forms does not support this yet.

  • adamkempadamkemp mod USInsider, Developer Group Leader mod

    How would it know which type arguments to use?

  • adamkempadamkemp mod USInsider, Developer Group Leader mod

    Try this:

    public class BindablePicker : Picker
    {
        // ...
    }
    
    public class BindablePicker<T> : BindablePicker
    {
        // ...
    }
    

    Then just use this one export:

    [assembly: ExportRenderer(typeof(BindablePicker), typeof(BindablePickerRenderer))]
    
  • SeanMattoxSeanMattox ✭✭ USMember ✭✭

    That depends significantly on what the underlying implementation looks like. C# knows that the type passed in is an unparameterized generic one; it is possible to make the leap from there that in the absence of a more specific mapping, the unparameterized generic could be fallen back to as a wildcard of sorts.

    My guess is that if there isn't some alternative means to specify this desire, though, that the module that handles this isn't set up to do so.

    This is doubly frustrating when the contents of the type argument isn't at all relevant to the renderer.

  • adamkempadamkemp mod USInsider, Developer Group Leader mod

    These exports get put into some map somewhere, and when it needs a renderer it looks in the map for the type of the Element. If the type isn't found it looks for the base type, and so on until it runs out of types to check. It would be inefficient to have to look for arbitrary generic types that don't exactly match the type of the Element because then it couldn't just do a simple dictionary lookup with hashing. It would have to use something more complex and slower.

    By inserting a type into the class hierarchy and using that for your export you can work within the current system, and everything can still be efficient.

Sign In or Register to comment.