Dashboard > Spring.NET > Interface constants using anonymous classes
  Spring.NET Log In View a printable version of the current page.  
  Interface constants using anonymous classes
Added by Aleksandar Seovic, last edited by Aleksandar Seovic on May 01, 2004
Labels: 
(None)

Some of the Spring Java interfaces contain constants that are declared in the interface iself and initialized using anonymous class that implements that same interface. You can find one example of this construct in ClassFilter interface:

public interface ClassFilter
{

    /**
     * Should the pointcut apply to the given interface or target class?
     *
     * @param clazz candidate target class
     * @return whether the advice should apply to this candidate target class
     */
    boolean matches(Class clazz);


    /**
     * Canonical instance of a ClassFilter that matches all classes.
     */
    ClassFilter TRUE = new ClassFilter()
    {
        public boolean matches(Class clazz)
        {
            return true;
        }
    };

}

JLCA will convert this into an interface, class that implements that interface and a struct that contains the constant TRUE itself. After class and struct names are changed manually, JLCS generated code would look like this:

public interface IClassFilter
{
    /// <summary>Should the pointcut apply to the given interface or target class?</summary>
    /// <param name="clazz">candidate target class</param>
    /// <returns> whether the advice should apply to this candidate target class
    /// </returns>
    bool Matches(Type clazz);
}

/// <summary>
/// ClassFilter constants.
/// 
/// <i>Note: .Net does not allow fields in interfaces nor anonymous classes
/// so we had to move canonical instance of IClassFilter to ClassFilter struct.</i>
/// </summary>
public struct ClassFilter
{
    /// <summary>
    /// Canonical instance of IClassFilter that matches all classes
    /// </summary>
    public readonly static IClassFilter TRUE;
    
    static ClassFilter()
    {
        TRUE = new TrueClassFilter();
    }
}

/// <summary>
/// Implementation of IClassFilter that matches all classes.
/// </summary>
internal class TrueClassFilter : IClassFilter
{
    public virtual bool Matches(System.Type clazz)
    {
        return true;
    }
}

There is really no need for the struct in this case. What's even worse, using this approach we would have to create a new class for each constant that we would like to define.

Better solution for this construct is this:

/// <summary>
/// IClassFilter constants.
/// 
/// <i>Note: .Net does not allow fields in interfaces nor anonymous classes
/// so we had to move canonical instance of IClassFilter to ClassFilter class.</i>
/// </summary>
public class ClassFilter : IClassFilter
{
    /// <summary>
    /// Canonical instance of IClassFilter that matches all classes
    /// </summary>
    public readonly static IClassFilter TRUE = new ClassFilter(true, "ClassFilter.TRUE");

    // instance variables
    bool _matches;
    string _toString;

    // constructors
    private ClassFilter(bool matches, string toString)
    {
        this._matches = matches;
        this._toString = toString;
    }

    /// <summary>Should the pointcut apply to the given interface or target class?</summary>
    /// <param name="clazz">candidate target class</param>
    /// <returns> whether the advice should apply to this candidate target class</returns>
    public virtual bool Matches(Type clazz)
    {
        return _matches;
    }

    /// <summary>
    /// Returns description of this class filter
    /// </summary>
    /// <returns>description of the class filter</returns>
    public override string ToString()
    {
        return _toString;
    }
}

As you can see, class itself holds singleton instance of each constant, and because constants are defined using constructor arguments it is fairly easy to add another constant if we wish.

Site running on a free Atlassian Confluence Open Source Project License granted to Spring Framework. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.5 Build:#811 Jul 25, 2007) - Bug/feature request - Contact Administrators