0

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; }
}


nop
  • 4,711
  • 6
  • 32
  • 93
  • when you already know why it doesn't compile, what exactly is your problem? What error exactly do you get? Honestly I didn't even find the correct spot within this huge code. – MakePeaceGreatAgain Oct 27 '22 at 15:30
  • It’s a decompiled code, that’s why it looks so hard to follow. The question is why dotPeek represents memberExpression1 and memberExpression2 like that e.g. memberExpression2 is not even defined. Maybe it was supposed to be a lambda or something? – nop Oct 27 '22 at 15:37
  • de-compiled code is not ment to be compiled again. I.e. things go weird if you de-compile anonymous functions. – MakePeaceGreatAgain Oct 27 '22 at 15:39
  • Just replace `is not MemberExpression memberExpression1/2` by `is not MemberExpression` – Olivier Jacot-Descombes Oct 27 '22 at 15:41

1 Answers1

1

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.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188