1

Say that I have an object a, which is of class A:

abstract class A {
    public abstract SomeType SomeMethod(int i)
    public abstract SomeType SomeOtherMethod()
}

Can I/how do I create an object b, of class B - which, at run time, can take any object (say A), and wrap it:

class B {
   public void Wrap(object someObject) {}
}

such that i can write the following code:

var a = Factory.BuildAn<A>();
var b = new B();
b.Wrap(a);
b.SomeMethod(1);
blueberryfields
  • 45,910
  • 28
  • 89
  • 168
  • you can but I'm afraid it isn't worth it. see this: [Emitting Dynamic Methods and Assemblies](http://msdn.microsoft.com/en-us/library/8ffc3x75(v=vs.110).aspx) – Selman Genç Apr 02 '14 at 03:04
  • 1
    You cannot define abstract methods in non abstract class `A`. Also, abstract methods cannot have body. –  Apr 02 '14 at 03:04
  • @Selman22 oh my. that. it really sounds like i don't want to do this in c# – blueberryfields Apr 02 '14 at 03:09
  • Possibly related: http://stackoverflow.com/questions/1433531/castle-dynamic-proxy-creation – Nathan Apr 02 '14 at 03:13

2 Answers2

3

Am not sure what problem you're trying to solve with this, but here's what you asked.

class MyClass
{
    public int IntValue { get; set; }

    public string SomeMethod(int i)
    {
        return i.ToString();
    }
    public string SomeOtherMethod()
    {
        return "Hello";
    }
}

class Wrapper : DynamicObject
{
    private object wrappedObject;

    public Wrapper(object wrappedObject)
    {
        this.wrappedObject = wrappedObject;
    }

    private void Wrap(object someObject)
    {
        wrappedObject = someObject;
    }


    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        PropertyInfo prop = wrappedObject.GetType()
            .GetProperty(binder.Name, BindingFlags.Instance | BindingFlags.Public);
        if (prop == null)
        {
            result = null;
            return false;
        }

        result = prop.GetValue(wrappedObject, null);
        return true;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        PropertyInfo prop = wrappedObject.GetType()
            .GetProperty(binder.Name, BindingFlags.Instance | BindingFlags.Public);
        if (prop == null)
        {
            return false;
        }

        prop.SetValue(wrappedObject, value);
        return true;
    }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        MethodInfo method = wrappedObject.GetType()
            .GetMethod(binder.Name, BindingFlags.Instance | BindingFlags.Public);
        if (method == null)
        {
            result = null;
            return false;
        }

        result = method.Invoke(wrappedObject, args);
        return true;
    }
}

MyClass a = new MyClass();
dynamic d = new Wrapper(a);
d.IntValue = 5;
string s = d.SomeOtherMethod();
Console.WriteLine(a.IntValue);
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
2

Yes you can using dynamic typing in C#. Class B will look like this, and you will use it exactly how you use it in your question.

class B : DynamicObject
{
    object _object;
    public void Wrap(object someObject)
    {
        _object = someObject;
    }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        try
        {
            result = _object.GetType().InvokeMember(
                binder.Name,
                BindingFlags.InvokeMethod |
                BindingFlags.Public |
                BindingFlags.Instance,
                null, _object, args);
                return true;
        }
        catch
        {
            result = null;
            return false;
        }
    }
}
ahmelsayed
  • 7,125
  • 3
  • 28
  • 40