Last active
October 13, 2015 07:08
-
-
Save MatthewKing/4158409 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright Matthew King 2011-2013. | |
// Distributed under the Boost Software License, Version 1.0. | |
// (See http://www.boost.org/LICENSE_1_0.txt) | |
using System; | |
using System.Globalization; | |
using System.Linq.Expressions; | |
using System.Reflection; | |
/// <summary> | |
/// Provides various reflection-related methods. | |
/// </summary> | |
public static class Reflect | |
{ | |
/// <summary> | |
/// Returns the name of the property referred to by the specified property expression. | |
/// </summary> | |
/// <typeparam name="TSource"> | |
/// Type containing the property. | |
/// </typeparam> | |
/// <typeparam name="TProperty"> | |
/// Type of the property. | |
/// </typeparam> | |
/// <param name="propertyExpression"> | |
/// An Expression representing a Func mapping an instance of type TSource to an instance | |
/// of type TProperty. | |
/// </param> | |
/// <returns> | |
/// The name of the property referred to by the specified property expression. | |
/// </returns> | |
public static string GetPropertyName<TSource, TProperty>( | |
Expression<Func<TSource, TProperty>> propertyExpression) | |
{ | |
if (propertyExpression == null) | |
throw new ArgumentNullException( | |
"propertyExpression", | |
"propertyExpression should not be null."); | |
return GetPropertyInfo<TSource, TProperty>(propertyExpression).Name; | |
} | |
/// <summary> | |
/// Returns a PropertyInfo instance for the property referred to by the specified | |
/// property expression. | |
/// </summary> | |
/// <typeparam name="TSource"> | |
/// Type containing the property. | |
/// </typeparam> | |
/// <typeparam name="TProperty"> | |
/// Type of the property. | |
/// </typeparam> | |
/// <param name="propertyExpression"> | |
/// An Expression representing a Func mapping an instance of type TSource to an instance | |
/// of type TProperty. | |
/// </param> | |
/// <returns> | |
/// A PropertyInfo instance for the property referred to by the specified | |
/// property expression. | |
/// </returns> | |
public static PropertyInfo GetPropertyInfo<TSource, TProperty>( | |
Expression<Func<TSource, TProperty>> propertyExpression) | |
{ | |
if (propertyExpression == null) | |
throw new ArgumentNullException( | |
"propertyExpression", | |
"propertyExpression should not be null."); | |
Type sourceType = typeof(TSource); | |
MemberExpression member = propertyExpression.Body as MemberExpression; | |
if (member == null) | |
{ | |
string message = String.Format( | |
CultureInfo.InvariantCulture, | |
"Expression '{0}' refers to a method, not a property.", | |
propertyExpression.ToString()); | |
throw new ArgumentException(message); | |
} | |
PropertyInfo propertyInfo = member.Member as PropertyInfo; | |
if (propertyInfo == null) | |
{ | |
string message = String.Format( | |
CultureInfo.InvariantCulture, | |
"Expression '{0}' refers to a field, not a property.", | |
propertyExpression.ToString()); | |
throw new ArgumentException(message); | |
} | |
if (sourceType != propertyInfo.ReflectedType | |
&& !sourceType.IsSubclassOf(propertyInfo.ReflectedType)) | |
{ | |
string message = String.Format( | |
CultureInfo.InvariantCulture, | |
"Expresion '{0}' refers to a property that is not from type {1}.", | |
propertyExpression.ToString(), | |
sourceType); | |
throw new ArgumentException(message); | |
} | |
return propertyInfo; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright Matthew King 2011-2013. | |
// Distributed under the Boost Software License, Version 1.0. | |
// (See http://www.boost.org/LICENSE_1_0.txt) | |
using System; | |
using NUnit.Framework; | |
[TestFixture] | |
internal sealed class ReflectTests | |
{ | |
private sealed class ExampleClass | |
{ | |
public string field; | |
public string Method() { return null; } | |
public string Property { get; set; } | |
} | |
[Test] | |
public void GetPropertyName_ExpressionRefersToAMethod_ThrowsArgumentException() | |
{ | |
const string message = "Expression 'o => o.Method()' refers to a method, not a property."; | |
Assert.That(() => Reflect.GetPropertyName<ExampleClass, string>(o => o.Method()), | |
Throws.TypeOf<ArgumentException>() | |
.And.Message.Contains(message)); | |
} | |
[Test] | |
public void GetPropertyName_ExpressionRefersToAField_ThrowsArgumentException() | |
{ | |
const string message = "Expression 'o => o.field' refers to a field, not a property."; | |
Assert.That(() => Reflect.GetPropertyName<ExampleClass, string>(o => o.field), | |
Throws.TypeOf<ArgumentException>() | |
.And.Message.Contains(message)); | |
} | |
[Test] | |
public void GetPropertyName_ReturnsCorrectValue() | |
{ | |
var value = Reflect.GetPropertyName<ExampleClass, string>(o => o.Property); | |
var expected = "Property"; | |
Assert.That(value, Is.EqualTo(expected)); | |
} | |
[Test] | |
public void GetPropertyInfo_ExpressionRefersToAMethod_ThrowsArgumentException() | |
{ | |
const string message = "Expression 'o => o.Method()' refers to a method, not a property."; | |
Assert.That(() => Reflect.GetPropertyInfo<ExampleClass, string>(o => o.Method()), | |
Throws.TypeOf<ArgumentException>() | |
.And.Message.Contains(message)); | |
} | |
[Test] | |
public void GetPropertyInfo_ExpressionRefersToAField_ThrowsArgumentException() | |
{ | |
const string message = "Expression 'o => o.field' refers to a field, not a property."; | |
Assert.That(() => Reflect.GetPropertyInfo<ExampleClass, string>(o => o.field), | |
Throws.TypeOf<ArgumentException>() | |
.And.Message.Contains(message)); | |
} | |
[Test] | |
public void GetPropertyInfo_ReturnsCorrectValue() | |
{ | |
var value = Reflect.GetPropertyInfo<ExampleClass, string>(o => o.Property); | |
var expected = typeof(ExampleClass).GetProperty("Property"); | |
Assert.That(value, Is.EqualTo(expected)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment