[stringtemplate-interest] IAttributeRenderer and Type Inheritance in C#

Jonathan Buhacoff jonathan at buhacoff.net
Sun Oct 25 15:55:40 PDT 2009


The existing ST code already works for subclasses.  My implementation  
of the interface renderer also works for subclasses that implement the  
same interface, but not because I did anything special - we get this  
from the language itself and from the renderer implementation, if it  
uses instanceof.

I like the idea of using isInterface to automatically separate the two  
kinds of renderers for later, but then the programmer can't control  
which interface renderer will apply to a value that implements more  
than one registered interface.

If the code were changed to add to a list instead of a map/dictionary,  
the programmer could control priority but then you have the same  
performance problem that you mentioned, plus the programmer will be  
forced to register interface-based handlers in order, which is not  
consistent with the current registration interface.

If it's implemented with a map or dictionary I would warn users not to  
use values that implement more than one registered interface because  
the behavior will not be predictable. This may be the simplest route.


--
Jonathan Buhacoff
jonathan at buhacoff.net
--



On Oct 23, 2009, at 6:52 PM, Sam Harwell wrote:

> This semi-solves one problem, but doesn’t address another at all.  
> What if you want to add a renderer for “[non-interface] type X and  
> all types derived from X”? Also, it still doesn’t address the  
> performance issue of the feature itself. Below is one way it could  
> be implemented without changing the public interface.
>
> Covered:
> ·         Performance when the feature is not in use
>
> ·         Registering renderers for interface type
>
> Not covered:
> ·         Performance implication when a renderer is registered for  
> an interface type
>
> ·         Registering renderers for a base type and having it also  
> apply to derived types
>
>
>
>     public virtual void RegisterRenderer( Type attributeClassType,  
> IAttributeRenderer renderer )
>     {
>         Dictionary<Type, IAttributeRenderer> renderers;
>         // renderers for interface types are kept separately due to  
> their performance implications
>         if (!attributeClassType.IsInterface)
>         {
>             if (_attributeRenderers == null)
>                 _attributeRenderers = new Dictionary<Type,  
> IAttributeRenderer>();
>
>             renderers = _attributeRenderers;
>         }
>         else
>         {
>             if (_interfaceRenderers == null)
>                 _interfaceRenderers = new Dictionary<Type,  
> IAttributeRenderer>();
>
>             renderers = _interfaceRenderers;
>         }
>
>         renderers[attributeClassType] = renderer;
>     }
>
>     public virtual IAttributeRenderer GetAttributeRenderer( Type  
> attributeClassType )
>     {
>         IAttributeRenderer renderer = null;
>         if ( _attributeRenderers != null )
>         {
>             if ( ! 
> _attributeRenderers.TryGetValue( attributeClassType, out renderer ) )
>                 renderer = null;
>         }
>
>         // Only need to perform the expensive interface checks if  
> the user registered a renderer for an interface type
>         if (renderer == null && _interfaceRenderers != null)
>         {
>             renderer = _interfaceRenderers.FirstOrDefault(pair =>  
> pair.Key.IsAssignableFrom(attributeClassType)).Value;
>         }
>
>         if ( renderer != null )
>         {
>             // found it!
>             return renderer;
>         }
>
>         // we have no renderer overrides for the template or none  
> for class arg
>         // check parent template if we are embedded
>         if ( _enclosingInstance != null )
>         {
>             return  
> _enclosingInstance.GetAttributeRenderer( attributeClassType );
>         }
>         // else check group
>         return _group.GetAttributeRenderer( attributeClassType );
>     }
>
>
> From: stringtemplate-interest-bounces at antlr.org [mailto:stringtemplate-interest-bounces at antlr.org 
> ] On Behalf Of Jonathan Buhacoff
> Sent: Friday, October 23, 2009 6:55 PM
> To: StringTemplate Mailing List
> Subject: Re: [stringtemplate-interest] IAttributeRendererand Type  
> Inheritancein C#
>
> Hi Sam,
>
> My last suggestion solves the performance and priority issues:
>
> A separate method for setting a list of interface renderers
>
> Something like:  public void setRenderers(List<AttributeRenderer>  
> renderers)
>
> Then in StringTemplate this list of renderers would be checked only  
> if a class renderer wasnt found.
>
> Performance issues would then only affect people using this feature.
>
>
>
>
>
> Sent from my iPhone
>
> On Oct 22, 2009, at 9:10 PM, "Sam Harwell" <sharwell at pixelminegames.com 
> > wrote:
>
> Hi Vincent and Jonathan,
>
> I can’t tell who said what here due to the way your editors  
> formatted the text. I thought about a possible solution to the  
> performance problems I mentioned, but I don’t think it will be  
> viable. I thought about always caching the results of the lookup, so  
> object interfaces would only need to be checked the first time a  
> type was used in a template. Unfortunately, due to the way templates  
> inherit attribute renderers, several problems emerge:
>
> 1.       Caching the renderers would result in a copy of all type- 
> >renderer maps in every template, incurring both a space and time  
> overhead.
>
> 2.       Caching the renderers would break the attribute renderer  
> inheritance scheme.
>
> 3.       Not caching the renderers would mean checking all interface  
> base types and interfaces while walking up the template inheritance  
> chain. This would be a more substantial hit than GetAttribute,  
> likely more than doubling the time required to render templates.  
> I’ll profile this to make sure, but if my analysis proves correct  
> the feature will have to be completely reengineered before we could  
> talk about incorporating it into the library.
>
>
> Sam
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org/pipermail/stringtemplate-interest/attachments/20091025/09d2c25d/attachment-0001.html 


More information about the stringtemplate-interest mailing list