4

I'm using c#.
I have class

class A
{
   public void MyMethod(int x){//Do something...};
}

How can I call MyMethod without creating an instance of Class A?
Can I use delegate/Action or something else to do that?
*Without changing MyMethod to static function

Thanks

3
  • You can´t until the method CAN be called statically, which is done by making the method static. No other way. However why do you want this? Commented Apr 20, 2016 at 9:30
  • 2
    Care to explain why you need it? Commented Apr 20, 2016 at 9:31
  • Then the answer is: it won´t work at all. Commented Apr 20, 2016 at 9:32

3 Answers 3

16

You can do this... but you really, really shouldn't:

// DO NOT USE THIS CODE
using System;

public class Evil
{
    public void Method()
    {
        Console.WriteLine($"Is this null? {this == null}");
    }    
}


class Test
{
    static void Main()
    {
        var method = typeof(Evil).GetMethod("Method");
        var action = (Action<Evil>) Delegate.CreateDelegate(typeof(Action<Evil>), method);
        action(null);
    }    
}

Output:

Is this null? True

The CreateDelegate call creates an open instance delegate. From MSDN:

In the .NET Framework version 2.0, this method overload also can create open instance method delegates; that is, delegates that explicitly supply the hidden first argument of instance methods. For a detailed explanation, see the more general CreateDelegate(Type, Object, MethodInfo) method overload, which allows you to create all combinations of open or closed delegates for instance or static methods, and optionally to specify a first argument.

We then invoke the method passing null as the argument, so the method is invoked with this being null.

But you absolutely should not do this and if the interviewer really expected you to know about this, then that's more of a reflection on them than it is on you.

Instance methods are clearly intended to be invoked on actual instances.

Sign up to request clarification or add additional context in comments.

4 Comments

And with this being null, you'll get a NulllReferenceException when accessing instance variables.
@CodeCaster: Yes indeed.
In sum, any reflection question is a self-reflection
If you want to take the "without instance" requirement to an even more extreme level, you could instead create an instance method that is closed over a null reference, replacing Jon's action declaration with var action = (Action)Delegate.CreateDelegate(typeof(Action), null, method); Of course, the MSDN documentation explicitly says that this is a bad idea: "Invoking the delegate is like calling an instance method on a null instance, which is not a particularly useful thing to do."
4

No. An instance method requires an instance to be called.

An instance method is mainly important for two reasons:

  1. Having access to the members of the instance (this)
  2. Optionally, being a virtual (or interface) method, thus allowing implementations to conform to a given interface while providing their own concrete implementation

Without the instance, both of these are impossible. If you need neither, make your method static.

EDIT:

As Jon Skeet noted, it's possible to do this. I did vaguely remember there was some such weird case, but couldn't reproduce it myself, so I thought it simply doesn't work anymore for some reason, whatever. Turns out I just made a silly mistake in my sample :)

But note that even with this, the "reasons to use an instance method" above still hold - it doesn't allow you to do anything a static method wouldn't. In fact, extension methods are exactly "static methods pretending to be instance methods" for example. They just explicitly declare the this argument.

Unlike extension methods, I'd argue that this approach isn't "really C#". You're accessing the method as if it weren't a C# method. I don't consider this fundamentally different from using C# to write IL to call a method with a null "instance":

ldnull
call instance void NS.A::MyMethod()

(translated to ILGenerator.Emit, of course)

Or, for that matter, using C# to write a few bytes into memory, moving them to an executable page and executing.

The really important part is understanding that .NET and IL don't care about this. It doesn't exist in IL, it's a C# concept (also used in other languages, of course) and C# purposefully limits your capabilities of using this in a method for certain benefits. But other languages might do away with such a thing entirely, or use a different convention than "the first argument of an instance method is a reference to the object instance". There's plenty of other similar examples - e.g. IL doesn't differentiate between out and ref arguments.

This is very important when interoperating with non-C# code, or when dealing with potentially hostile code you're executing - do not assume that all C# limitations hold on .NET as a whole.

3 Comments

Have a look at my answer. It can be done. It just shouldn't.
@JonSkeet I actually tried to do the exact same thing by supplying a null Target, but that (correctly) fails on an exception. I guess the target-less delegate is important for interop with languages that don't have a concept of instance? That said, this is exactly the kind of interview question that either means you're interviewing for a pretty hard-core position, or that you should run away from that employer ASAP :D
Completely agree on this not being a good interview question. In terms of why it's allowed for delegates... I really don't know, to be honest.
1

Make it as static so that you need not to instantiate the class to call the method, so the class definition will be :

class A
{
   public static void MyMethod(int x){//Do something...};
}

So that you can call MyMethod like A.MyMethod(10);

Response to edit: You cannot access an instance method of a particular class without creating an instance, the only option is make it as static.

Comments

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.