/// <summary>
/// Creates a <see cref="MemberExpression" /> accessing a property.
/// </summary>
/// <param name="expression">The containing object of the property. This can be null for static properties.</param>
/// <param name="property">The property to be accessed.</param>
/// <returns>The created <see cref="MemberExpression" />.</returns>
public static MemberExpression Property(Expression?expression, PropertyInfo property)
{
ContractUtils.RequiresNotNull(property, nameof(property));
var mi = property.GetGetMethod(true);
if (mi == null)
{
mi = property.GetSetMethod(true);
if (mi == null)
{
throw new ArgumentException($"The property '{property}' has no 'get' or 'set' accessors", nameof(property));
}
if (mi.GetParameters().Length != 1)
{
throw new ArgumentException($"Incorrect number of arguments supplied for call to method '{mi}'", nameof(property));
}
}
else if (mi.GetParameters().Length != 0)
{
throw new ArgumentException($"Incorrect number of arguments supplied for call to method '{mi}'", nameof(property));
}
if (mi.IsStatic)
{
if (expression != null)
{
throw new ArgumentException("Static property requires null instance, non-static property requires non-null instance.", nameof(expression));
}
}
else
{
if (expression == null)
{
throw new ArgumentException("Static property requires null instance, non-static property requires non-null instance.", nameof(property));
}
ExpressionUtils.RequiresCanRead(expression, nameof(expression));
if (!TypeUtils.IsValidInstanceType(property, expression.Type))
{
throw new ArgumentException($"Property '{property}' is not defined for type '{expression.Type}'", nameof(property));
}
}
ValidateMethodInfo(mi, nameof(property));
return(MemberExpression.Make(expression, property));
}