1

Hi I have a namespace with a lot of classes and all of them has a method Destroy(int id) I want to call that method using dynamic word.

Here is my example:

public bool DeleteElement<T>(T tElement)
{
    Type t = typeof(T);

    dynamic element = tElement;
    var id = element.Id;

    //until here everything is fine
    //here I want to say 
    (namespace).myClassName.Destroy(id);
    //the name of  myClassName is like t.ToString()
}

I can avoid namespace including a using at the top. The idea is to call that static method using dynamic, not Reflection, please see that Destroy is a static method of T. I need something like this T.Destroy(id)

4
  • 2
    Which framework are you actually targeting? dynamic is not available in C# 3.0. Sounds like a good time for an interface... (and associated generic type constraint) Commented Jun 6, 2014 at 18:13
  • I put the question to people in C# 3.0 because someone could know about this Commented Jun 6, 2014 at 18:14
  • Ok, but it changes what we can use. We still need to know what framework elements are allowed. Commented Jun 6, 2014 at 18:15
  • 3
    @Zinov, people who follow the c#-3.0 tag usually follow the c# tag as well, so you don't really need to include all versions ;) Commented Jun 6, 2014 at 18:17

1 Answer 1

5

If Destroy(int id) is a static method, couldn't you create an instance method that would call the static one?

public void Destroy()
{
    ThisClass.Destroy(this.Id);
}

You could then define an IDestroyable interface implemented by all these classes:

interface IDestroyable { void Destroy(); }

And then modify your DeleteElement method as follows:

public bool DeleteElement<T>(T tElement) where T : IDestroyable
{
    tElement.Destroy();
}

No need to use dynamic here... Actually, using dynamic in this situation is often an indication of bad design. It's quite rare to actually need dynamic except in the scenarios for which it was created (e.g. interop with dynamic languages)

(If the classes are generated but they have the partial modifier, you can declare the new method in another file that is not touched by the generator)


EDIT: if the classes are generated and are not partial, you can't modify them... So another solution would be to use reflection; I know you want to avoid that (for performance reasons I assume), but you can limit the performance impact by doing the reflection only once for each type: you just need to create and cache a delegate for each type.

class DestroyHelper<T>
{
    static readonly Action<int> _destroy;
    static readonly Func<T, int> _getId;
    static DestroyHelper()
    {
        var destroyMethod = typeof(T).GetMethod("Destroy", BindingFlags.Static | BindingFlags.Public);
        _destroy = (Action<int>)Delegate.CreateDelegate(typeof(Action<int>), destroyMethod);
        var getIdMethod = typeof(T).GetProperty("Id").GetGetMethod();
        _getId = (Func<T, int>)Delegate.CreateDelegate(typeof(Func<T, int>), getIdMethod);
    }

    public static void Destroy(T element)
    {
        _destroy(_getId(element));
    }
}
Sign up to request clarification or add additional context in comments.

16 Comments

Nop all the classes are generated, every time that something change I need to fix all code putting the inheritance to IDestroyable, this is not the approach that I am looking for
@Zinov, I assume you have no control over the generation of these classes? And are they by chance declared as partial? If they are, my solution can still work.
@Zinov, I wasn't suggesting to use reflection (in my original answer). I don't think it's possible to call static methods with dynamic; I edited my answer to provide a solution that uses reflection but limits the performance impact.
As for reflection: how do you think dynamic works? When working with objects that are not intrinsically dynamic, it uses reflection, because it's the only way to access members that are not known statically. Of course, it does it in a very optimized way, using caches and such, but it has to use reflection. If you think you can make your code more efficient with dynamic than with reflection, think again ;)
@Zinov, I'm pretty sure it's not possible to do it with dynamic. The interface approach is probably the best, since it only uses the static type system and doesn't involve reflection.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.