ReflectionUtilsTests.cs :  » Inversion-of-Control-Dependency-Injection » Spring.net » Spring » Util » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Inversion of Control Dependency Injection » Spring.net 
Spring.net » Spring » Util » ReflectionUtilsTests.cs
#region License

/*
 * Copyright 2004 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#endregion

#region Imports

using System;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
using NUnit.Framework;

using Spring.Objects;
using Spring.Objects.Factory;
using Spring.Objects.Factory.Attributes;

#endregion

#if NET_2_0
[assembly: InternalsVisibleTo( "ReflectionUtils.IsTypeVisible.AssemblyTestName, PublicKey=001200000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293" )]
#endif

namespace Spring.Util{
    /// <summary>
    /// Unit tests for the ReflectionUtils class.
    /// </summary>
    [TestFixture]
    public sealed class ReflectionUtilsTests
    {
        #region MapsInterfaceMethodsToImplementation utility classes

        interface IMapsInterfaceMethodInterface
        {
            void SomeMethodA();
            void SomeMethodB();
            object SomeProperty { get; }
        }

        public class MapsInterfaceMethodClass : IMapsInterfaceMethodInterface
        {
            public MethodInfo MethodAInfo;
            public MethodInfo MethodBInfo;
            public MethodInfo PropGetterInfo;

            public MapsInterfaceMethodClass()
            {
                SomeMethodA();
                ((IMapsInterfaceMethodInterface)this).SomeMethodB();
                object o = ((IMapsInterfaceMethodInterface)this).SomeProperty;
            }

            public void SomeMethodA()
            {
                MethodAInfo = (MethodInfo)MethodInfo.GetCurrentMethod();
            }

            void IMapsInterfaceMethodInterface.SomeMethodB()
            {
                MethodBInfo = (MethodInfo)MethodInfo.GetCurrentMethod();
            }

            object IMapsInterfaceMethodInterface.SomeProperty
            {
                get
                {
                    PropGetterInfo = (MethodInfo)MethodInfo.GetCurrentMethod();
                    return null;
                }
            }
        }

        #endregion

        private class DummyException : ApplicationException
        {
            public DummyException() : base("dummy message")
            {
            }
        }

        public static void ThrowDummyException()
        {
            throw new DummyException();
        }

        public delegate void VoidAction();

        [Test]
        public void UnwrapsTargetInvocationException()
        {
            if (SystemUtils.MonoRuntime)
            {
#if DEBUG
                // TODO (EE): find solution for Mono
                return;
#endif
            }

            MethodInfo mi = new VoidAction(ThrowDummyException).Method;
            try
            {
                try
                {
                    mi.Invoke(null, null);
                    Assert.Fail();
                }
                catch(TargetInvocationException tie)
                {
//                    Console.WriteLine(tie);
                    throw ReflectionUtils.UnwrapTargetInvocationException(tie);
                }
                Assert.Fail();
            }
            catch (DummyException e)
            {
//                Console.WriteLine(e);
                string[] stackFrames = e.StackTrace.Split('\n');
#if !MONO
                // TODO: mono includes the invoke() call in inner stackframe does not include the outer stackframes - either remove or document it
                string firstFrameMethodName = mi.DeclaringType.FullName + "." + mi.Name;
                AssertStringContains( firstFrameMethodName, stackFrames[0]);
                string lastFrameMethodName = MethodBase.GetCurrentMethod().DeclaringType.FullName + "." + MethodBase.GetCurrentMethod().Name;
                AssertStringContains(lastFrameMethodName, stackFrames[stackFrames.Length-1]);

#endif
            }
        }

        private void AssertStringContains(string toSearch, string source)
        {
            if (source.IndexOf(toSearch) == -1)
            {
                Assert.Fail("Expected '{0}' contained in source, but not found. Source was {1}", toSearch, source);
            }
        }

        [Test]
        public void MapsInterfaceMethodsToImplementation()
        {
            MapsInterfaceMethodClass instance = new MapsInterfaceMethodClass();
            MethodInfo method = null;

            try
            {
                method = ReflectionUtils.MapInterfaceMethodToImplementationIfNecessary( null, typeof( MapsInterfaceMethodClass ) );
                Assert.Fail();
            }
            catch (ArgumentNullException ex)
            {
                Assert.AreEqual("methodInfo", ex.ParamName);
            }

            try
            {
                method = ReflectionUtils.MapInterfaceMethodToImplementationIfNecessary( (MethodInfo)MethodInfo.GetCurrentMethod(), null );
                Assert.Fail();
            }
            catch (ArgumentNullException ex)
            {
                Assert.AreEqual("implementingType", ex.ParamName);
            }

            try
            {
                // unrelated types
                method = ReflectionUtils.MapInterfaceMethodToImplementationIfNecessary( (MethodInfo)MethodInfo.GetCurrentMethod(), typeof( MapsInterfaceMethodClass ) );
                Assert.Fail();
            }
            catch (ArgumentException ex)
            {
                Assert.AreEqual("methodInfo and implementingType are unrelated", ex.Message);
            }

            method = ReflectionUtils.MapInterfaceMethodToImplementationIfNecessary( typeof( MapsInterfaceMethodClass ).GetMethod( "SomeMethodA" ), typeof( MapsInterfaceMethodClass ) );
            Assert.AreSame( instance.MethodAInfo, method );
            method = ReflectionUtils.MapInterfaceMethodToImplementationIfNecessary( typeof( IMapsInterfaceMethodInterface ).GetMethod( "SomeMethodA" ), typeof( MapsInterfaceMethodClass ) );
            Assert.AreSame( instance.MethodAInfo, method );
            method = ReflectionUtils.MapInterfaceMethodToImplementationIfNecessary( typeof( IMapsInterfaceMethodInterface ).GetMethod( "SomeMethodB" ), typeof( MapsInterfaceMethodClass ) );
            Assert.AreSame( instance.MethodBInfo, method );
            method = ReflectionUtils.MapInterfaceMethodToImplementationIfNecessary( typeof( IMapsInterfaceMethodInterface ).GetProperty( "SomeProperty" ).GetGetMethod(), typeof( MapsInterfaceMethodClass ) );
            Assert.AreSame( instance.PropGetterInfo, method );
        }

        #region Helper class for http://jira.springframework.org/browse/SPRNET-992 tests

        public class Foo
        {
            public readonly string a = "";
            public readonly int b = -1;
            public readonly char c = '0';

            public Foo( string a, int b, char c )
            {
                this.a = a;
                this.b = b;
                this.c = c;
            }

            public Foo( string a )
            {
                this.a = a;
            }

            public Foo()
            {
            }
        }

        #endregion

        [Test( Description = "http://jira.springframework.org/browse/SPRNET-992" )]
        public void ShouldPickDefaultConstructorWithoutArgs()
        {
            object[] args = new object[] { };
            ConstructorInfo best = ReflectionUtils.GetConstructorByArgumentValues( typeof( Foo ).GetConstructors(), null );
            Foo foo = (Foo)best.Invoke( args );

            Assert.AreEqual( "", foo.a );
            Assert.AreEqual( -1, foo.b );
            Assert.AreEqual( '0', foo.c );
        }

        [Test( Description = "http://jira.springframework.org/browse/SPRNET-992" )]
        public void ShouldPickDefaultConstructor()
        {
            object[] args = new object[] { };
            ConstructorInfo best = ReflectionUtils.GetConstructorByArgumentValues( typeof( Foo ).GetConstructors(), args );
            Foo foo = (Foo)best.Invoke( args );

            Assert.AreEqual( "", foo.a );
            Assert.AreEqual( -1, foo.b );
            Assert.AreEqual( '0', foo.c );
        }

        [Test( Description = "http://jira.springframework.org/browse/SPRNET-992" )]
        public void ShouldPickSingleArgConstructor()
        {
            object[] args = new object[] { "b" };
            ConstructorInfo best = ReflectionUtils.GetConstructorByArgumentValues( typeof( Foo ).GetConstructors(), args );
            Foo foo = (Foo)best.Invoke( args );

            Assert.AreEqual( "b", foo.a );
            Assert.AreEqual( -1, foo.b );
            Assert.AreEqual( '0', foo.c );
        }

        [Test]
        public void GetParameterTypes()
        {
            Type[] expectedParameterTypes = new Type[] { typeof( string ) };
            MethodInfo method = typeof( ReflectionUtilsObject ).GetMethod( "BadSpanglish" );
            Type[] parameterTypes = ReflectionUtils.GetParameterTypes( method );
            Assert.IsTrue( ArrayUtils.AreEqual( expectedParameterTypes, parameterTypes ) );
        }

        [Test]
        [ExpectedException( typeof( ArgumentNullException ) )]
        public void GetParameterTypesWithNullMethodInfo()
        {
            ReflectionUtils.GetParameterTypes( (MethodInfo)null );
        }

        [Test]
        [ExpectedException( typeof( ArgumentNullException ) )]
        public void GetParameterTypesWithNullParametersArgs()
        {
            ReflectionUtils.GetParameterTypes( (ParameterInfo[])null );
        }

        [Test]
        [ExpectedException( typeof( ArgumentNullException ) )]
        public void GetMatchingMethodsWithNullTypeToFindOn()
        {
            ReflectionUtils.GetMatchingMethods( null, new MethodInfo[] { }, true );
        }

        [Test]
        [ExpectedException( typeof( ArgumentNullException ) )]
        public void GetMatchingMethodsWithNullMethodsToFind()
        {
            ReflectionUtils.GetMatchingMethods( GetType(), null, true );
        }

        [Test]
        public void GetMatchingMethodsWithPerfectMatch()
        {
            MethodInfo[] clonesMethods = typeof( ReflectionUtilsObjectClone ).GetMethods( BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance );
            MethodInfo[] foundMethods = ReflectionUtils.GetMatchingMethods( typeof( ReflectionUtilsObject ), clonesMethods, true );
            Assert.AreEqual( clonesMethods.Length, foundMethods.Length );
        }

        [Test]
        [ExpectedException( typeof( Exception ) )]
        public void GetMatchingMethodsWithBadMatchStrict()
        {
            // lets include a protected method that ain't declared on the ReflectionUtilsObject class...
            MethodInfo[] clonesMethods = typeof( ReflectionUtilsObjectClone ).GetMethods( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Instance );
            ReflectionUtils.GetMatchingMethods( typeof( ReflectionUtilsObject ), clonesMethods, true );
        }

        [Test]
        public void GetMatchingMethodsWithBadMatchNotStrict()
        {
            // lets include a protected method that ain't declared on the ReflectionUtilsObject class...
            MethodInfo[] clonesMethods = typeof( ReflectionUtilsObjectClone ).GetMethods( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Instance );
            MethodInfo[] foundMethods = ReflectionUtils.GetMatchingMethods( typeof( ReflectionUtilsObject ), clonesMethods, false );
            // obviously is not strict, 'cos we got here without throwing an exception...
            Assert.AreEqual( clonesMethods.Length, foundMethods.Length );
        }

        [Test]
        [ExpectedException( typeof( Exception ) )]
        public void GetMatchingMethodsWithBadReturnTypeMatchStrict()
        {
            // lets include a method that return type is different...
            MethodInfo[] clonesMethods = typeof( ReflectionUtilsObjectBadClone ).GetMethods( BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance );
            ReflectionUtils.GetMatchingMethods( typeof( ReflectionUtilsObject ), clonesMethods, true );
        }

        [Test]
        public void GetMatchingMethodsWithBadReturnTypeMatchNotStrict()
        {
            // lets include a method that return type is different...
            MethodInfo[] clonesMethods = typeof( ReflectionUtilsObjectBadClone ).GetMethods( BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance );
            MethodInfo[] foundMethods = ReflectionUtils.GetMatchingMethods( typeof( ReflectionUtilsObject ), clonesMethods, false );
            // obviously is not strict, 'cos we got here without throwing an exception...
            Assert.AreEqual( clonesMethods.Length, foundMethods.Length );
        }

        [Test]
        public void ParameterTypesMatch()
        {
            MethodInfo method = typeof( ReflectionUtilsObject ).GetMethod( "Spanglish" );
            Type[] types = new Type[] { typeof( string ), typeof( object[] ) };
            Assert.IsTrue( ReflectionUtils.ParameterTypesMatch( method, types ) );
        }

        [Test]
        public void ParameterTypesDontMatchWithNonMatchingArgs()
        {
            Type[] types = new Type[] { typeof( string ), typeof( object[] ) };

            MethodInfo method = typeof( ReflectionUtilsObject ).GetMethod( "BadSpanglish" );
            Assert.IsFalse( ReflectionUtils.ParameterTypesMatch( method, types ) );
            method = typeof( ReflectionUtilsObject ).GetMethod( "WickedSpanglish" );
            Assert.IsFalse( ReflectionUtils.ParameterTypesMatch( method, types ) );
        }

        [Test]
        public void GetDefaultValue()
        {
            Assert.IsNull( ReflectionUtils.GetDefaultValue( GetType() ) );
            Assert.AreEqual( Cuts.Superficial, ReflectionUtils.GetDefaultValue( typeof( Cuts ) ) );
            Assert.AreEqual( false, ReflectionUtils.GetDefaultValue( typeof( bool ) ) );
            Assert.AreEqual( DateTime.MinValue, ReflectionUtils.GetDefaultValue( typeof( DateTime ) ) );
            Assert.AreEqual( Char.MinValue, ReflectionUtils.GetDefaultValue( typeof( char ) ) );
            Assert.AreEqual( 0, ReflectionUtils.GetDefaultValue( typeof( long ) ) );
            Assert.AreEqual( 0, ReflectionUtils.GetDefaultValue( typeof( int ) ) );
            Assert.AreEqual( 0, ReflectionUtils.GetDefaultValue( typeof( short ) ) );
        }

        [Test]
        public void PropertyIsIndexer()
        {
            Assert.IsTrue( ReflectionUtils.PropertyIsIndexer( "Item", typeof( TestObject ) ) );
            Assert.IsFalse( ReflectionUtils.PropertyIsIndexer( "Item", typeof( SideEffectObject ) ) );
            Assert.IsFalse( ReflectionUtils.PropertyIsIndexer( "Count", typeof( SideEffectObject ) ) );
            Assert.IsTrue( ReflectionUtils.PropertyIsIndexer( "MyItem", typeof( ObjectWithNonDefaultIndexerName ) ) );
        }

        [Test]
        public void MethodIsOnOneOfTheseInterfaces()
        {
            MethodInfo method = typeof( ReflectionUtilsObject ).GetMethod( "Spanglish" );
            Assert.IsTrue( ReflectionUtils.MethodIsOnOneOfTheseInterfaces( method, new Type[] { typeof( IFoo ) } ) );
        }

        [Test]
        [ExpectedException( typeof( ArgumentException ) )]
        public void MethodIsOnOneOfTheseInterfacesWithNonInterfaceType()
        {
            MethodInfo method = typeof( ReflectionUtilsObject ).GetMethod( "Spanglish" );
            Assert.IsFalse( ReflectionUtils.MethodIsOnOneOfTheseInterfaces( method, new Type[] { GetType() } ) );
        }

        [Test]
        [ExpectedException( typeof( ArgumentNullException ) )]
        public void MethodIsOnOneOfTheseInterfacesWithNullMethod()
        {
            MethodInfo method = null;
            Assert.IsFalse( ReflectionUtils.MethodIsOnOneOfTheseInterfaces( method, new Type[] { GetType() } ) );
        }

        [Test]
        public void MethodIsOnOneOfTheseInterfacesWithNullTypes()
        {
            MethodInfo method = typeof( ReflectionUtilsObject ).GetMethod( "Spanglish" );
            Assert.IsFalse( ReflectionUtils.MethodIsOnOneOfTheseInterfaces( method, null ) );
        }

        [Test]
        public void MethodIsOnOneOfTheseInterfacesMultiple()
        {
            MethodInfo method = typeof( RequiredTestObject ).GetMethod( "set_ObjectFactory" );
            Assert.IsNotNull( method, "Could not get setter property for ObjectFactory" );
            Assert.IsTrue( ReflectionUtils.MethodIsOnOneOfTheseInterfaces( method, new Type[] { typeof( IObjectNameAware ), typeof( IObjectFactoryAware ) } ) );
        }


        [Test]
        [ExpectedException( typeof( ArgumentNullException ) )]
        public void ParameterTypesMatchWithNullArgs()
        {
            ReflectionUtils.ParameterTypesMatch( null, null );
        }

        [Test]
        public void GetSignature()
        {
            MethodInfo method = typeof( ReflectionUtilsObject ).GetMethod( "Spanglish" );
            ArrayList list = new ArrayList();
            foreach (ParameterInfo p in method.GetParameters())
            {
                list.Add( p.ParameterType );
            }
            string expected = "Spring.Util.ReflectionUtilsObject::Spanglish(System.String,System.Object[])";
            Type[] pTypes = (Type[])list.ToArray( typeof( Type ) );
            string actual = ReflectionUtils.GetSignature( method.DeclaringType, method.Name, pTypes );
            Assert.AreEqual( expected, actual );
        }

        [Test]
        public void ToInterfaceArrayFromType()
        {
            Type[] expected = new Type[] { typeof( IFoo ), typeof( IBar ) };
            Type[] actual = ReflectionUtils.ToInterfaceArray( typeof( IBar ) );
            Assert.AreEqual( expected.Length, actual.Length );
            Assert.AreEqual( expected[0], actual[0] );
            Assert.AreEqual( expected[1], actual[1] );
        }

        [Test]
        [ExpectedException( typeof( ArgumentException ) )]
        public void ToInterfaceArrayFromTypeWithNonInterface()
        {
            ReflectionUtils.ToInterfaceArray( typeof( ExplicitFoo ) );
        }


        [Test]
        public void GetMethod()
        {
            MethodInfo actual = ReflectionUtils.GetMethod(
                typeof( ReflectionUtilsObject ),
                "Spanglish",
                new Type[] { typeof( string ), typeof( object[] ) } );
            Assert.IsNotNull( actual );
        }

        [Test]
        public void GetMethodWithExplicitInterfaceMethod()
        {
            MethodInfo actual = ReflectionUtils.GetMethod(
                typeof( ExplicitFoo ),
                "Spring.Util.IFoo.Spanglish",
                new Type[] { typeof( string ), typeof( object[] ) } );
            Assert.IsNotNull( actual );
        }

        [Test]
        public void GetMethodIsCaseInsensitive()
        {
            MethodInfo actual = ReflectionUtils.GetMethod(
                typeof( ReflectionUtilsObject ),
                "spAngLISh",
                new Type[] { typeof( string ), typeof( object[] ) } );
            Assert.IsNotNull( actual, "ReflectionUtils.GetMethod would appear to be case sensitive." );
        }

        [Test]
        [ExpectedException( typeof( ArgumentException ),
            ExpectedMessage = "[Spring.Util.ReflectionUtilsTests] does not derive from the [System.Attribute] class." )]
        public void CreateCustomAttributeForNonAttributeType()
        {
            ReflectionUtils.CreateCustomAttribute( GetType() );
        }

        [Test]
        [ExpectedException( typeof( ArgumentNullException ) )]
        public void CreateCustomAttributeWithNullType()
        {
            ReflectionUtils.CreateCustomAttribute( (Type)null );
        }

        [Test]
        public void CreateCustomAttributeSunnyDayScenarios()
        {
            CustomAttributeBuilder builder = null;

            builder = ReflectionUtils.CreateCustomAttribute( typeof( MyCustomAttribute ) );
            Assert.IsNotNull( builder );

            builder = ReflectionUtils.CreateCustomAttribute( typeof( MyCustomAttribute ), "Rick" );
            Assert.IsNotNull( builder );

            builder = ReflectionUtils.CreateCustomAttribute( typeof( MyCustomAttribute ), "Rick" );
            Assert.IsNotNull( builder );

            builder = ReflectionUtils.CreateCustomAttribute( new MyCustomAttribute( "Rick" ) );
            Assert.IsNotNull( builder );

            builder = ReflectionUtils.CreateCustomAttribute( typeof( MyCustomAttribute ), new MyCustomAttribute( "Rick" ) );
            Assert.IsNotNull( builder );

            builder = ReflectionUtils.CreateCustomAttribute( typeof( MyCustomAttribute ), new object[] { "Rick" }, new MyCustomAttribute( "Evans" ) );
            Assert.IsNotNull( builder );

            // TODO : actually emit the attribute and check it...
        }
#if NET_2_0
        [Test]
        public void CreatCustomAttriubtesFromCustomAttributeData()
        {
            Type control = typeof( Control );
            MethodInfo mi = control.GetMethod( "get_Font" );
            System.Collections.Generic.IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes( mi.ReturnParameter );
            CustomAttributeBuilder builder = null;
            foreach (CustomAttributeData customAttributeData in attributes)
            {
                builder = ReflectionUtils.CreateCustomAttribute( customAttributeData );
                Assert.IsNotNull( builder );
            }

        }
#endif
        [Test]
        public void CreateCustomAttributeUsingDefaultValuesForTheConstructor()
        {
            CustomAttributeBuilder builder = null;
            builder = ReflectionUtils.CreateCustomAttribute( typeof( AnotherCustomAttribute ) );
            Assert.IsNotNull( builder );

            AnotherCustomAttribute att
                = (AnotherCustomAttribute)CheckForPresenceOfCustomAttribute( builder, typeof( AnotherCustomAttribute ) );
            Assert.IsNull( att.Name );
            Assert.AreEqual( 0, att.Age );
            Assert.IsFalse( att.HasSwallowedExplosives );
        }

        [Test]
        public void CreateCustomAttributeFromSourceAttribute()
        {
            CustomAttributeBuilder builder = null;
            AnotherCustomAttribute source = new AnotherCustomAttribute( "Rick", 30, true );
            builder = ReflectionUtils.CreateCustomAttribute( source );
            Assert.IsNotNull( builder );

            AnotherCustomAttribute att
                = (AnotherCustomAttribute)CheckForPresenceOfCustomAttribute( builder, typeof( AnotherCustomAttribute ) );
            Assert.AreEqual( source.Name, att.Name );
            Assert.AreEqual( source.Age, att.Age );
            Assert.AreEqual( source.HasSwallowedExplosives, att.HasSwallowedExplosives );
        }

        [Test]
        public void CreateCustomAttributeUsingExplicitValuesForTheConstructor()
        {
            CustomAttributeBuilder builder = null;
            const string expectedName = "Rick";
            const int expectedAge = 30;
            builder = ReflectionUtils.CreateCustomAttribute( typeof( AnotherCustomAttribute ), new object[]
        {
          expectedName, expectedAge, true
        } );
            Assert.IsNotNull( builder );

            AnotherCustomAttribute att
                = (AnotherCustomAttribute)CheckForPresenceOfCustomAttribute( builder, typeof( AnotherCustomAttribute ) );
            Assert.AreEqual( expectedName, att.Name );
            Assert.AreEqual( expectedAge, att.Age );
            Assert.IsTrue( att.HasSwallowedExplosives );
        }

        [Test]
        public void CreateCustomAttributeUsingExplicitValuesForTheConstructorAndASourceAttribute()
        {
            CustomAttributeBuilder builder = null;
            const string expectedName = "Rick";
            const int expectedAge = 30;
            AnotherCustomAttribute source = new AnotherCustomAttribute( expectedName, expectedAge, false );
            builder = ReflectionUtils.CreateCustomAttribute( typeof( AnotherCustomAttribute ), new object[]
        {
          "Hoop", 2, true
        }, source );
            Assert.IsNotNull( builder );

            AnotherCustomAttribute att
                = (AnotherCustomAttribute)CheckForPresenceOfCustomAttribute( builder, typeof( AnotherCustomAttribute ) );
            Assert.AreEqual( expectedName, att.Name );
            Assert.AreEqual( expectedAge, att.Age );
            Assert.IsFalse( att.HasSwallowedExplosives );
        }

        [Test]
        public void HasAtLeastOneMethodWithName()
        {
            Type testType = typeof( ExtendedReflectionUtilsObject );
            // declared method...
            Assert.IsTrue( ReflectionUtils.HasAtLeastOneMethodWithName( testType, "Declared" ) );
            // case insensitive method...
            Assert.IsTrue( ReflectionUtils.HasAtLeastOneMethodWithName( testType, "deCLAReD" ) );
            // superclass method...
            Assert.IsTrue( ReflectionUtils.HasAtLeastOneMethodWithName( testType, "Spanglish" ) );
            // static method...
            Assert.IsTrue( ReflectionUtils.HasAtLeastOneMethodWithName( testType, "Static" ) );
            // protected method...
            Assert.IsTrue( ReflectionUtils.HasAtLeastOneMethodWithName( testType, "Protected" ) );
            // non existent method...
            Assert.IsFalse( ReflectionUtils.HasAtLeastOneMethodWithName( testType, "Sponglish" ) );
            // null type...
            Assert.IsFalse( ReflectionUtils.HasAtLeastOneMethodWithName( null, "Spanglish" ) );
            // null method name...
            Assert.IsFalse( ReflectionUtils.HasAtLeastOneMethodWithName( testType, null ) );
            // empty method name...
            Assert.IsFalse( ReflectionUtils.HasAtLeastOneMethodWithName( testType, "" ) );
            // all nulls...
            Assert.IsFalse( ReflectionUtils.HasAtLeastOneMethodWithName( null, null ) );
        }

        [Test]
        [ExpectedException( typeof( NullReferenceException ) )]
        public void GetTypeOfOrTypeWithNull()
        {
            ReflectionUtils.TypeOfOrType( null );
        }

        [Test]
        public void GetTypeOfOrType()
        {
            Assert.AreEqual( typeof( string ), ReflectionUtils.TypeOfOrType( typeof( string ) ) );
        }

        [Test]
        public void GetTypeOfOrTypeWithNonNullType()
        {
            Assert.AreEqual( typeof( string ), ReflectionUtils.TypeOfOrType( string.Empty ) );
        }

        [Test]
        public void GetTypes()
        {
            Type[] actual = ReflectionUtils.GetTypes(
                new object[] { 1, "I've never been to Taco Bell (sighs).", new ReflectionUtilsObject() } );
            Type[] expected = new Type[]
        {
          typeof (int),
          typeof (string),
          typeof (ReflectionUtilsObject),
      };
            Assert.IsTrue( ArrayUtils.AreEqual( expected, actual ), "The ReflectionUtils.GetTypes method did not return a correct Type [] array. Yep, that's as helpful as it gets." );
        }

        [Test]
        public void GetTypesWithEmptyArrayArgument()
        {
            Type[] actual = ReflectionUtils.GetTypes( new object[] { } );
            Assert.IsNotNull( actual, "The ReflectionUtils.GetTypes method returned null when given an empty array. Must return an empty Type [] array." );
            Assert.IsTrue( actual.Length == 0, "The ReflectionUtils.GetTypes method returned a Type [] that had some elements in it when given an empty array. Must return an empty Type [] array." );
        }

        [Test]
        public void GetTypesWithNullArrayArgument()
        {
            Type[] actual = ReflectionUtils.GetTypes( null );
            Assert.IsNotNull( actual, "The ReflectionUtils.GetTypes method returned null when given null. Must return an empty Type [] array." );
            Assert.IsTrue( actual.Length == 0, "The ReflectionUtils.GetTypes method returned a Type [] that had some elements in it when given null. Must return an empty Type [] array." );
        }

        [Test]
        [ExpectedException( typeof( ArgumentException ) )]
        public void GetDefaultValueWithZeroValueEnumType()
        {
            ReflectionUtils.GetDefaultValue( typeof( EnumWithNoValues ) );
        }

        [Test]
        public void GetParameterTypesWithMethodThatHasRefParameters()
        {
            MethodInfo method = GetType().GetMethod( "Add" );
            Type[] types = ReflectionUtils.GetParameterTypes( method );
            Assert.IsNotNull( types );
            Assert.AreEqual( 2, types.Length );
            // first method parameter is byRef, so type name must end in '&'
            Assert.AreEqual( "System.Int32&", types[0].FullName );
            Assert.AreEqual( "System.Int32", types[1].FullName );
        }

        [Test]
        public void GetMethodByArgumentValuesResolvesToExactMatchIfAvailable()
        {
            GetMethodByArgumentValuesTarget.DummyArgumentType[] typedArg = new GetMethodByArgumentValuesTarget.DummyArgumentType[] { };
            GetMethodByArgumentValuesTarget foo = new GetMethodByArgumentValuesTarget( 1, typedArg );

            Type type = typeof( GetMethodByArgumentValuesTarget );
            MethodInfo[] candidateMethods = new MethodInfo[]
                {
                    type.GetMethod("MethodWithSimilarArguments", new Type[] {typeof(int), typeof(ICollection)})
                    , type.GetMethod("MethodWithSimilarArguments", new Type[] {typeof(int), typeof(GetMethodByArgumentValuesTarget.DummyArgumentType[])})
                    , type.GetMethod("MethodWithSimilarArguments", new Type[] {typeof(int), typeof(object[])})
                };

            // ensure noone changed our test class
            Assert.IsNotNull( candidateMethods[0] );
            Assert.IsNotNull( candidateMethods[1] );
            Assert.IsNotNull( candidateMethods[2] );
            Assert.AreEqual( "ParamArrayMatch", foo.MethodWithSimilarArguments( 1, new object() ) );
            Assert.AreEqual( "ExactMatch", foo.MethodWithSimilarArguments( 1, (GetMethodByArgumentValuesTarget.DummyArgumentType[])typedArg ) );
            Assert.AreEqual( "AssignableMatch", foo.MethodWithSimilarArguments( 1, (ICollection)typedArg ) );

            MethodInfo resolvedMethod = ReflectionUtils.GetMethodByArgumentValues( candidateMethods, new object[] { 1, typedArg } );
            Assert.AreSame( candidateMethods[1], resolvedMethod );
        }

        [Test]
        public void GetConstructorByArgumentValuesResolvesToExactMatchIfAvailable()
        {
            GetMethodByArgumentValuesTarget.DummyArgumentType[] typedArg = new GetMethodByArgumentValuesTarget.DummyArgumentType[] { };
            Type type = typeof( GetMethodByArgumentValuesTarget );
            ConstructorInfo[] candidateConstructors = new ConstructorInfo[]
                {
                    type.GetConstructor(new Type[] {typeof(int), typeof(ICollection)})
                    , type.GetConstructor(new Type[] {typeof(int), typeof(GetMethodByArgumentValuesTarget.DummyArgumentType[])})
                    , type.GetConstructor(new Type[] {typeof(int), typeof(object[])})
                };

            // ensure noone changed our test class
            Assert.IsNotNull( candidateConstructors[0] );
            Assert.IsNotNull( candidateConstructors[1] );
            Assert.IsNotNull( candidateConstructors[2] );
            Assert.AreEqual( "ParamArrayMatch", new GetMethodByArgumentValuesTarget( 1, new object() ).SelectedConstructor );
            Assert.AreEqual( "ExactMatch", new GetMethodByArgumentValuesTarget( 1, (GetMethodByArgumentValuesTarget.DummyArgumentType[])typedArg ).SelectedConstructor );
            Assert.AreEqual( "AssignableMatch", new GetMethodByArgumentValuesTarget( 1, (ICollection)typedArg ).SelectedConstructor );

            ConstructorInfo resolvedConstructor = ReflectionUtils.GetConstructorByArgumentValues( candidateConstructors, new object[] { 1, typedArg } );
            Assert.AreSame( candidateConstructors[1], resolvedConstructor );
        }

        #region GetInterfaces

        [Test]
        public void GetInterfaces()
        {
            Assert.AreEqual(
                typeof( TestObject ).GetInterfaces().Length,
                ReflectionUtils.GetInterfaces( typeof( TestObject ) ).Length );

            Assert.AreEqual( 1, ReflectionUtils.GetInterfaces( typeof( IInterface1 ) ).Length );
            Assert.AreEqual( 4, ReflectionUtils.GetInterfaces( typeof( IInterface2 ) ).Length );
        }

        public interface IInterface1
        {
        }

        public interface IInterface2 : IInterface3
        {
        }

        public interface IInterface3 : IInterface4, IInterface5
        {
        }

        public interface IInterface4
        {
        }

        public interface IInterface5
        {
        }

        #endregion

        #region IsTypeVisible Tests

        [Test]
        public void IsTypeVisibleWithInternalType()
        {
            Type type = typeof( InternalType );
            Assert.IsFalse( ReflectionUtils.IsTypeVisible( type ) );
        }

        [Test]
        public void IsTypeVisibleWithPublicNestedTypeOnInternalType()
        {
            Type type = typeof( InternalType.PublicNestedType );
            Assert.IsFalse( ReflectionUtils.IsTypeVisible( type ) );
        }

        [Test]
        public void IsTypeVisibleWithInternalNestedTypeOnInternalType()
        {
            Type type = typeof( InternalType.InternalNestedType );
            Assert.IsFalse( ReflectionUtils.IsTypeVisible( type ) );
        }

        [Test]
        public void IsTypeVisibleWithProtectedInternalNestedTypeOnInternalType()
        {
            Type type = typeof( InternalType.ProtectedInternalNestedType );
            Assert.IsFalse( ReflectionUtils.IsTypeVisible( type ) );
        }

        [Test]
        public void IsTypeVisibleWithProtectedNestedTypeOnInternalType()
        {
            Type type = typeof( InternalType ).GetNestedType( "ProtectedNestedType", BindingFlags.NonPublic );
            Assert.IsFalse( ReflectionUtils.IsTypeVisible( type ) );
        }

        [Test]
        public void IsTypeVisibleWithPrivateNestedTypeOnInternalType()
        {
            Type type = typeof( InternalType ).GetNestedType( "PrivateNestedType", BindingFlags.NonPublic );
            Assert.IsFalse( ReflectionUtils.IsTypeVisible( type ) );
        }

        [Test]
        public void IsTypeVisibleWithPublicType()
        {
            Type type = typeof( PublicType );
            Assert.IsTrue( ReflectionUtils.IsTypeVisible( type ) );
        }

        [Test]
        public void IsTypeVisibleWithPublicNestedTypeOnPublicType()
        {
            Type type = typeof( PublicType.PublicNestedType );
            Assert.IsTrue( ReflectionUtils.IsTypeVisible( type ) );
        }

        [Test]
        public void IsTypeVisibleWithInternalNestedTypeOnPublicType()
        {
            Type type = typeof( PublicType.InternalNestedType );
            Assert.IsFalse( ReflectionUtils.IsTypeVisible( type ) );
        }

        [Test]
        public void IsTypeVisibleWithProtectedInternalNestedTypeOnPublicType()
        {
            Type type = typeof( PublicType.ProtectedInternalNestedType );
            Assert.IsFalse( ReflectionUtils.IsTypeVisible( type ) );
        }

        [Test]
        public void IsTypeVisibleWithProtectedNestedTypeOnPublicType()
        {
            Type type = typeof( PublicType ).GetNestedType( "ProtectedNestedType", BindingFlags.NonPublic );
            Assert.IsFalse( ReflectionUtils.IsTypeVisible( type ) );
        }

        [Test]
        public void IsTypeVisibleWithPrivateNestedTypeOnPublicType()
        {
            Type type = typeof( PublicType ).GetNestedType( "PrivateNestedType", BindingFlags.NonPublic );
            Assert.IsFalse( ReflectionUtils.IsTypeVisible( type ) );
        }

#if NET_2_0
        private static readonly string FRIENDLY_ASSEMBLY_NAME = "ReflectionUtils.IsTypeVisible.AssemblyTestName, PublicKey=001200000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293";

        [Test]
        public void IsTypeVisibleFromFriendlyAssemblyWithInternalType()
        {
            Type type = typeof( InternalType );
            Assert.IsTrue( ReflectionUtils.IsTypeVisible( type, FRIENDLY_ASSEMBLY_NAME ) );
        }

        [Test]
        public void IsTypeVisibleFromFriendlyAssemblyWithPublicNestedTypeOnInternalType()
        {
            Type type = typeof( InternalType.PublicNestedType );
            Assert.IsTrue( ReflectionUtils.IsTypeVisible( type, FRIENDLY_ASSEMBLY_NAME ) );
        }

        [Test]
        public void IsTypeVisibleFromFriendlyAssemblyWithInternalNestedTypeOnInternalType()
        {
            Type type = typeof( InternalType.InternalNestedType );
            Assert.IsTrue( ReflectionUtils.IsTypeVisible( type, FRIENDLY_ASSEMBLY_NAME ) );
        }

        [Test]
        public void IsTypeVisibleFromFriendlyAssemblyWithProtectedInternalNestedTypeOnInternalType()
        {
            Type type = typeof( InternalType.ProtectedInternalNestedType );
            Assert.IsTrue( ReflectionUtils.IsTypeVisible( type, FRIENDLY_ASSEMBLY_NAME ) );
        }

        [Test]
        public void IsTypeVisibleFromFriendlyAssemblyWithProtectedNestedTypeOnInternalType()
        {
            Type type = typeof( InternalType ).GetNestedType( "ProtectedNestedType", BindingFlags.NonPublic );
            Assert.IsFalse( ReflectionUtils.IsTypeVisible( type, FRIENDLY_ASSEMBLY_NAME ) );
        }

        [Test]
        public void IsTypeVisibleFromFriendlyAssemblyWithPrivateNestedTypeOnInternalType()
        {
            Type type = typeof( InternalType ).GetNestedType( "PrivateNestedType", BindingFlags.NonPublic );
            Assert.IsFalse( ReflectionUtils.IsTypeVisible( type, FRIENDLY_ASSEMBLY_NAME ) );
        }

        [Test]
        public void IsTypeVisibleFromFriendlyAssemblyWithPublicType()
        {
            Type type = typeof( PublicType );
            Assert.IsTrue( ReflectionUtils.IsTypeVisible( type, FRIENDLY_ASSEMBLY_NAME ) );
        }

        [Test]
        public void IsTypeVisibleFromFriendlyAssemblyWithPublicNestedTypeOnPublicType()
        {
            Type type = typeof( PublicType.PublicNestedType );
            Assert.IsTrue( ReflectionUtils.IsTypeVisible( type, FRIENDLY_ASSEMBLY_NAME ) );
        }

        [Test]
        public void IsTypeVisibleFromFriendlyAssemblyWithInternalNestedTypeOnPublicType()
        {
            Type type = typeof( PublicType.InternalNestedType );
            Assert.IsTrue( ReflectionUtils.IsTypeVisible( type, FRIENDLY_ASSEMBLY_NAME ) );
        }

        [Test]
        public void IsTypeVisibleFromFriendlyAssemblyWithProtectedInternalNestedTypeOnPublicType()
        {
            Type type = typeof( PublicType.ProtectedInternalNestedType );
            Assert.IsTrue( ReflectionUtils.IsTypeVisible( type, FRIENDLY_ASSEMBLY_NAME ) );
        }

        [Test]
        public void IsTypeVisibleFromFriendlyAssemblyWithProtectedNestedTypeOnPublicType()
        {
            Type type = typeof( PublicType ).GetNestedType( "ProtectedNestedType", BindingFlags.NonPublic );
            Assert.IsFalse( ReflectionUtils.IsTypeVisible( type, FRIENDLY_ASSEMBLY_NAME ) );
        }

        [Test]
        public void IsTypeVisibleFromFriendlyAssemblyWithPrivateNestedTypeOnPublicType()
        {
            Type type = typeof( PublicType ).GetNestedType( "PrivateNestedType", BindingFlags.NonPublic );
            Assert.IsFalse( ReflectionUtils.IsTypeVisible( type, FRIENDLY_ASSEMBLY_NAME ) );
        }
#endif

        #endregion

        #region GetExplicitBaseException

        [Test]
        public void GetExplicitBaseExceptionWithNoInnerException()
        {
            Exception appEx = new ApplicationException();
            Exception ex = ReflectionUtils.GetExplicitBaseException( appEx );

            Assert.AreEqual( ex, appEx );
        }

        [Test]
        public void GetExplicitBaseExceptionWithInnerException()
        {
            Exception dbzEx = new DivideByZeroException();
            Exception appEx = new ApplicationException( "Test message", dbzEx );
            Exception ex = ReflectionUtils.GetExplicitBaseException( appEx );

            Assert.AreEqual( ex, dbzEx );
        }

        [Test]
        public void GetExplicitBaseExceptionWithInnerExceptions()
        {
            Exception dbzEx = new DivideByZeroException();
            Exception sEx = new SystemException( "Test message", dbzEx );
            Exception appEx = new ApplicationException( "Test message", sEx );
            Exception ex = ReflectionUtils.GetExplicitBaseException( appEx );

            Assert.AreEqual( ex, dbzEx );
        }

        [Test]
        public void GetExplicitBaseExceptionWithNullReferenceExceptionAsRootException()
        {
            Exception nrEx = new NullReferenceException();
            Exception appEx = new ApplicationException( "Test message", nrEx );
            Exception ex = ReflectionUtils.GetExplicitBaseException( appEx );

            Assert.AreEqual( ex, appEx );
        }

        #endregion

        #region Helper Methods

        public int Add( ref int one, int two )
        {
            return one + two;
        }

        private Attribute CheckForPresenceOfCustomAttribute(
            CustomAttributeBuilder attBuilder, Type attType )
        {
            Attribute[] atts = ApplyAndGetCustomAttributes( attBuilder );
            Assert.IsNotNull( atts );
            Assert.IsTrue( atts.Length == 1 );
            Attribute att = atts[0];
            Assert.IsNotNull( att );
            Assert.AreEqual( attType, att.GetType(), "Wrong Attribute applied to the class." );
            return att;
        }

        private static Attribute[] ApplyAndGetCustomAttributes( CustomAttributeBuilder attBuilder )
        {
            Type type = BuildTypeWithThisCustomAttribute( attBuilder );
            object[] attributes = type.GetCustomAttributes( true );
            return (Attribute[])ArrayList.Adapter( attributes ).ToArray( typeof( Attribute ) );
        }

        private static Type BuildTypeWithThisCustomAttribute( CustomAttributeBuilder attBuilder )
        {
            AssemblyName assemblyName = new AssemblyName();
            assemblyName.Name = "AnAssembly";
            AssemblyBuilder asmBuilder = Thread.GetDomain().DefineDynamicAssembly(
                assemblyName, AssemblyBuilderAccess.Run );
            ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule( "AModule" );
            TypeBuilder classBuilder = modBuilder.DefineType( "AClass", TypeAttributes.Public );
            classBuilder.SetCustomAttribute( attBuilder );
            return classBuilder.CreateType();
        }

        #endregion
    }

    #region Simple Helper Classes

    public class PublicType
    {
        public class PublicNestedType
        {
        }

        internal class InternalNestedType
        {
        }

        protected internal class ProtectedInternalNestedType
        {
        }

        protected class ProtectedNestedType
        {
        }

        private class PrivateNestedType
        {
        }
    }

    internal class InternalType
    {
        public class PublicNestedType
        {
        }

        internal class InternalNestedType
        {
        }

        protected internal class ProtectedInternalNestedType
        {
        }

        protected class ProtectedNestedType
        {
        }

        private class PrivateNestedType
        {
        }
    }

    internal enum EnumWithNoValues { }

    internal enum Cuts
    {
        Superficial,
        Deep,
        Severing
    }

    internal interface IBar : IFoo
    {
    }

    internal interface IFoo
    {
        bool Spanglish( string foo, object[] args );
    }

    internal sealed class ExplicitFoo : IFoo
    {
        bool IFoo.Spanglish( string foo, object[] args )
        {
            return false;
        }
    }

    internal class ReflectionUtilsObject : IComparable
    {
        public bool Spanglish( string foo, object[] args )
        {
            return false;
        }

        public bool BadSpanglish( string foo )
        {
            return false;
        }

        public bool WickedSpanglish( string foo, string bar )
        {
            return false;
        }

        /// <summary>
        /// Explicit interface implementation for ReflectionUtils.GetMethod tests
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        int IComparable.CompareTo( object obj )
        {
            return 0;
        }
    }

    internal sealed class ExtendedReflectionUtilsObject : ReflectionUtilsObject
    {
        public void Declared( string name )
        {
        }

        public void Protected()
        {
        }

        public static void Static()
        {
        }
    }

    /// <summary>
    /// Exposes methods with the same names as the ReflectionUtilsObject, used in
    /// the tests for the GetMatchingMethods method.
    /// </summary>
    internal class ReflectionUtilsObjectClone
    {
        public bool Spanglish( string foo, object[] args )
        {
            return false;
        }

        public bool BadSpanglish( string foo )
        {
            return false;
        }

        public bool WickedSpanglish( string foo, string bar )
        {
            return false;
        }

        protected void Bingo()
        {
        }
    }

    /// <summary>
    /// Exposes methods with the same names as the ReflectionUtilsObject, used in
    /// the tests for the GetMatchingMethods method.
    /// </summary>
    internal class ReflectionUtilsObjectBadClone
    {
        public bool Spanglish( string foo, object[] args )
        {
            return false;
        }

        public string BadSpanglish( string foo )
        {
            return foo;
        }

        public bool WickedSpanglish( string foo, string bar )
        {
            return false;
        }
    }

    internal class GetMethodByArgumentValuesTarget
    {
        public class DummyArgumentType { }

        public string SelectedConstructor;

        public GetMethodByArgumentValuesTarget( int flag, params object[] values )
        {
            SelectedConstructor = "ParamArrayMatch";
        }

        public GetMethodByArgumentValuesTarget( int flag, DummyArgumentType[] bars )
        {
            SelectedConstructor = "ExactMatch";
        }

        public GetMethodByArgumentValuesTarget( int flag, ICollection bars )
        {
            SelectedConstructor = "AssignableMatch";
        }

        public string MethodWithSimilarArguments( int flags, params object[] args )
        {
            return "ParamArrayMatch";
        }

        public string MethodWithSimilarArguments( int flags, DummyArgumentType[] bars )
        {
            return "ExactMatch";
        }

        public string MethodWithSimilarArguments( int flags, ICollection bar )
        {
            return "AssignableMatch";
        }
    }

    public sealed class MyCustomAttribute : Attribute
    {
        public MyCustomAttribute()
        {
        }

        public MyCustomAttribute( string name )
        {
            _name = name;
        }

        public string Name
        {
            get { return _name; }
        }

        private string _name;
    }

    /// <summary>
    /// Used for testing that default values are supplied for the ctor args.
    /// </summary>
    public sealed class AnotherCustomAttribute : Attribute
    {
        public AnotherCustomAttribute( string name, int age, bool hasSwallowedExplosives )
        {
            _name = name;
            _age = age;
            _hasSwallowedExplosives = hasSwallowedExplosives;
        }

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public int Age
        {
            get { return _age; }
            set { _age = value; }
        }

        public bool HasSwallowedExplosives
        {
            get { return _hasSwallowedExplosives; }
            set { _hasSwallowedExplosives = value; }
        }

        private string _name;
        private int _age;
        private bool _hasSwallowedExplosives;
    }

    public sealed class ObjectWithNonDefaultIndexerName
    {
        private string[] favoriteQuotes = new string[10];

        [IndexerName( "MyItem" )]
        public string this[int index]
        {
            get
            {
                if (index < 0 || index >= favoriteQuotes.Length)
                {
                    throw new ArgumentException( "Index out of range" );
                }
                return favoriteQuotes[index];
            }

            set
            {
                if (index < 0 || index >= favoriteQuotes.Length)
                {
                    throw new ArgumentException( "index is out of range." );
                }
                favoriteQuotes[index] = value;
            }

        }
    }
    #endregion
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.