I'm looking at the following decompiled code and it wouldn't compile because of memberExpression1
and memberExpression2
. How do I put the puzzles back, so it compiles?
using System.Globalization;
using System.Linq.Expressions;
using System.Reflection;
namespace Test;
public class RoutingDetail
{
protected RoutingDetail(IEnumerable<KeyValuePair<string, string>> routingParameters)
{
RoutingKeyParameters = routingParameters;
}
public IEnumerable<KeyValuePair<string, string>> RoutingKeyParameters { get; }
}
public class RoutingDetail<TMessage> : RoutingDetail
{
public RoutingDetail()
: base(new Dictionary<string, string>())
{
}
private RoutingDetail(IEnumerable<KeyValuePair<string, string>> routingParameters)
: base(routingParameters)
{
}
public RoutingDetail<TMessage> WithRoutingHeader(
KeyValuePair<string, string> routingHeader)
{
var dictionary = RoutingKeyParameters.ToDictionary(k => k.Key, k => k.Value);
dictionary.Add(routingHeader.Key, routingHeader.Value);
return new RoutingDetail<TMessage>(dictionary);
}
public RoutingDetail<TMessage> WithRoutingHeader<TRoutingValue>(
Expression<Func<TMessage, TRoutingValue>> property,
TRoutingValue value)
{
var dictionary = RoutingKeyParameters.ToDictionary(k => k.Key, k => k.Value);
var nameValueFromFunc = GetValidPropertyNameValueFromFunc(property, value);
dictionary.Add(nameValueFromFunc.Key, nameValueFromFunc.Value);
return new RoutingDetail<TMessage>(dictionary);
}
private KeyValuePair<string, string> GetValidPropertyNameValueFromFunc<TProperty>(
Expression<Func<TMessage, TProperty>> property,
TProperty value)
{
if (property.Body is not MemberExpression memberExpression1)
{
if (property.Body.NodeType is ExpressionType.Convert or ExpressionType.ConvertChecked &&
property.Body is UnaryExpression body)
{
memberExpression1 = body.Operand as MemberExpression;
}
if (memberExpression1 == null)
{
throw new ArgumentException($"Expression '{property}' refers to a method, not a property.");
}
}
var member1 = memberExpression1.Member as PropertyInfo;
var key = (object)member1 != null
? member1.Name
: throw new ArgumentException($"Expression '{property}' refers to a field, not a property.");
if (CustomAttributeExtensions.GetCustomAttributes(member1, typeof(RouteOnAttribute), true)
.FirstOrDefault() is not RouteOnAttribute routeOnAttribute1)
{
throw new ArgumentException(
$"Property {key} does not have the RouteOn attribute, and will not be used when routing. ");
}
memberExpression2 = memberExpression1;
while (memberExpression2.Expression is MemberExpression memberExpression2)
{
var member2 = memberExpression2.Member as PropertyInfo;
if ((object)member2 == null)
{
throw new ArgumentException($"Expression '{property}' refers to a field, not a property.");
}
key = $"{member2.Name}.{key}";
if (CustomAttributeExtensions.GetCustomAttributes(member2, typeof(RouteOnAttribute), true)
.FirstOrDefault() is not RouteOnAttribute routeOnAttribute2)
{
throw new ArgumentException(
$"Property {member1.Name} does not have the RouteOn attribute, and will not be used when routing. ");
}
if (!routeOnAttribute2.UseInnerProperties)
{
throw new ArgumentException(
$"Property {member1.Name} does not have the UseInnerProperties attribute set, and will not be used when routing.");
}
}
return new KeyValuePair<string, string>(key,
string.Format(CultureInfo.InvariantCulture, routeOnAttribute1.FormatString, value));
}
}
[AttributeUsage(AttributeTargets.Property)]
public class RouteOnAttribute : Attribute
{
public RouteOnAttribute()
{
FormatString = "{0}";
UseInnerProperties = false;
}
public string FormatString { get; set; }
public bool UseInnerProperties { get; set; }
}
CodePudding user response:
Convert if (property.Body is not MemberExpression memberExpression1){ ... }
to
var memberExpression1 = property.Body as MemberExpression;
if (memberExpression1 is null) {
if (property.Body.NodeType is ExpressionType.Convert or ExpressionType.ConvertChecked &&
property.Body is UnaryExpression body) {
memberExpression1 = body.Operand as MemberExpression;
}
if (memberExpression1 == null) {
throw new ArgumentException($"Expression '{property}' refers to a method, not a property.");
}
}
Convert
memberExpression2 = memberExpression1;
while (memberExpression2.Expression is MemberExpression memberExpression2) { ... }
to
MemberExpression memberExpression2 = memberExpression1;
while (memberExpression2.Expression is MemberExpression) { ... }
It is not advisable to copy/paste code that you don't understand.