public void PropertyInfoThroughLambda()
{
{
// Both types are inferred (holder and property type).
// Requires an instance of the holder.
string oneInstance = null;
PropertyInfo i = ReflectionHelper.GetPropertyInfo( oneInstance, s => s.Length );
Assert.That( i.Name, Is.EqualTo( "Length" ) );
Assert.That( i.PropertyType, Is.SameAs( typeof( int ) ) );
Assert.Throws<ArgumentException>( () => ReflectionHelper.GetPropertyInfo( oneInstance, s => s.IndexOf( 'e' ) ) );
}
{
// Same as before, but default() is used to "obtain" an instance of the holder type.
// To avoid this, next versions can be used.
PropertyInfo i = ReflectionHelper.GetPropertyInfo( default( KeyValuePair<int, long> ), p => p.Value );
Assert.That( i.Name, Is.EqualTo( "Value" ) );
Assert.That( i.PropertyType, Is.SameAs( typeof( long ) ) );
}
{
// This version avoids the instance (but requires the holder type to be specified).
PropertyInfo i = ReflectionHelper.GetPropertyInfo<string>( s => s.Length );
Assert.That( i.Name, Is.EqualTo( "Length" ) );
Assert.That( i.PropertyType, Is.SameAs( typeof( int ) ) );
Assert.Throws<ArgumentException>( () => ReflectionHelper.GetPropertyInfo<string>( s => s.IndexOf( 'e' ) ) );
}
{
// This version avoids the instance (but requires the holder type to be specified),
// and enables property type checking.
//
// PropertyInfo iFail = Helper.GetPropertyInfo<string, byte>( s => s.Length );
PropertyInfo i = ReflectionHelper.GetPropertyInfo<string, int>( s => s.Length );
Assert.That( i.Name, Is.EqualTo( "Length" ) );
Assert.That( i.PropertyType, Is.SameAs( typeof( int ) ) );
}
{
// This version uses the closure to capture the reference to the property.
PropertyInfo i = ReflectionHelper.GetPropertyInfo( () => AnIntProperty );
Assert.That( i.Name, Is.EqualTo( "AnIntProperty" ) );
Assert.That( i.PropertyType, Is.SameAs( typeof( int ) ) );
PropertyInfo i2 = ReflectionHelper.GetPropertyInfo( () => i.Name );
Assert.That( i2.Name, Is.EqualTo( "Name" ) );
Assert.That( i2.PropertyType, Is.SameAs( typeof( string ) ) );
byte[] anArray = new byte[1];
Assert.Throws<ArgumentException>( () => ReflectionHelper.GetPropertyInfo( () => anArray[0] ) );
}
{
// This version uses the closure to capture the reference to the property
// and enables property type checking.
// PropertyInfo iFail = Helper.GetPropertyInfo<string>( () => AnIntProperty );
PropertyInfo i = ReflectionHelper.GetPropertyInfo<int>( () => AnIntProperty );
Assert.That( i.Name, Is.EqualTo( "AnIntProperty" ) );
Assert.That( i.PropertyType, Is.SameAs( typeof( int ) ) );
PropertyInfo i2 = ReflectionHelper.GetPropertyInfo<string>( () => i.Name );
Assert.That( i2.Name, Is.EqualTo( "Name" ) );
Assert.That( i2.PropertyType, Is.SameAs( typeof( string ) ) );
// REVIEW: change .Clone() to .ToString().
Assert.Throws<ArgumentException>( () => ReflectionHelper.GetPropertyInfo( () => i2.Name.ToString() ) );
}
}