Home > Software engineering >  Unable to compile decompiled code via dotPeek
Unable to compile decompiled code via dotPeek

Time:10-28

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.

  • Related