Czy istnieje sposób na zbudowanie obiektu Expento z klasy podstawowej innej firmy?
Innymi słowy, próbuję zrobić coś takiego:

// Instantiate my Expando object
dynamic myDynamicObject = new ExpandoObject();
// Add some base class to it - SomeBaseClass() can contain anything (Properties and methods)
myDynamicObject =  Add SomeBaseClass(); ???
// Add some other properties that are not in the base class
myDynamicObject.Name = "My Dynamic Object";
// Add some methods
myDynamicObject.SomeMethods = (Func<bool>)(() => {
   return true;
});

EDYTOWAĆ

Jak sugerowany przez Muithena, możemy zbudować Expando z innego obiektu zgodnie z tym stackoverflow Wątek. Oto, co robią:

public static dynamic ToDynamic<T>(this T obj)
{
   IDictionary<string, object> expando = new ExpandoObject();

   foreach (var propertyInfo in typeof(T).GetProperties())
   {
       var currentValue = propertyInfo.GetValue(obj);
       expando.Add(propertyInfo.Name, currentValue);
   }
   return expando as ExpandoObject;
}

Jednak ten przykład dba o właściwości, ale potrzebuję także metod.

Próbowałem więc zrobić coś podobnego do metod, ale tak naprawdę nie wiem, co robię tutaj:

public static dynamic ToDynamic<T>(this T obj)
{
   IDictionary<string, object> expando = new ExpandoObject();

   MethodInfo[] info = typeof(T).GetMethods();

   foreach (var methodInfo in info)
   {
      if (methodInfo != null)
      {
          var currentMethod = methodInfo.GetMethodBody();
          expando.Add(methodInfo.Name, currentMethod);
      }
   }
   return expando as ExpandoObject;
}

Ale wtedy próbując wykonać metody, otrzymuję ten błąd:

An unhandled exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in Unknown Module.

Informacje dodatkowe: Nie można wywołać typu nie-delegata

0
stackMeUp 20 marzec 2020, 12:38

1 odpowiedź

Najlepsza odpowiedź

Na podstawie Ta odpowiedź, z niewielkim zamiennikiem, aby nie polegać na zajęciach dodatkowej

public class Expando : DynamicObject
{
    public object Instance;
    Dictionary<string, dynamic> ExtraProperties = new Dictionary<string, dynamic>();

    public Expando(object instance)
    {
        Instance = instance;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        try
        {
            result = Instance.GetType().GetProperty(binder.Name).GetValue(Instance,null);
            return true;
        }
        catch
        {
            if (ExtraProperties.Keys.Contains(binder.Name))
            {
                result = ExtraProperties[binder.Name];
                return true;
            }
        }

        result = null;
        return false;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        try
        {
            Instance.GetType().GetProperty(binder.Name).SetValue(Instance, value,null);
        }
        catch (Exception ex)
        {
            ExtraProperties[binder.Name] = value;
        }

        return true;
    }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        try
        {
            result = Instance.GetType().GetMethod(binder.Name,args.Select(a=>a.GetType()).ToArray()).Invoke(Instance, args);
            return true;
        }
        catch
        { }

        result = null;
        return false;
    }

    public override string ToString()
    {
        return Instance.ToString();
    }

}

Powinien awarii i wzmacniacz; Burn na zajęciach, których używasz, wypróbuj oryginalną odpowiedź (jeśli dodatkowa klasa nie została zaktualizowana, użyj https://github.com/rickstrahl/westwind.Utilities/blob/master/westwind.Tilities/efultectionutils.cs

Należy pamiętać, że typ powrotu członków nie zostanie zmieniony. Oznacza to, że jeśli na przykład, używasz Expento na sznurku, Twój Expento odpowiada na zastąpienie i łopatkę, ale zwrócony wynik jest łańcuchem, a nie Twój Expento, który może nie być tym, co chcesz. Musisz włączyć go z powrotem do twojego Expando, jeśli nadal go potrzebujesz. Również to rozwiązanie jest ślepe na metody rozszerzeń, które mogą mieć zastosowanie do oryginalnej klasy.

1
Martheen 20 marzec 2020, 20:02