5

I heard that C# is a pure object-oriented programming language, because all of things are derived from System.Object.

So I doubt what's the type of the Method itself. I tried with StackTrace and StackFrame to get type of method, but I just got the name of class, which methods are declared.

Of course, I tried this:

var func = new TestClass().TestMethod; //TestMethod is a method of TestClass

however I got only this error.

CS0815    Cannot assign method group to an implicitly-typed variable 

Methods can be assigned to Func<..., TResult>typed variables. I tested with Func and method that returns string, then I got this:

// Result of
// Func<string> func = new TestClass().TestMethod;
// func.GetType();
Instance TestClass -> TestMethod Type : System.Func`1[System.String]

But it's a typename of Func<string>. So, What's the real typename of methods?

Edit Feb 10, 2018 01:46 AM, KST (GMT +09:00)

Alright, let me summarize. Function itself have no type, also it is not an object, and Delegate / Func<> is a just feature of .NET Framework to handle functions as first class citizen(but it is not an FCC). is it correct?

Kangjun Heo
  • 1,023
  • 1
  • 8
  • 19
  • 1
    You might be common from native C++, where it is possibly to assign any function that returns type T, to any pointer on T. And call it like that. Well, the .NET Framework design team went to great lenghts so you would never have to handle naked pointers. Delegates are just one of those replacements. Personally I find this way better, because the Compiler can check if what you are doing makes sense. – Christopher Feb 09 '18 at 16:42
  • 1
    A method is not an object therefore it has no type. A method in C# is the object oriented way of attaching functions to classes, but they are not first class citizens as functions are in JavaScript. – Carlos Muñoz Feb 09 '18 at 16:43
  • 1
    https://stackoverflow.com/questions/1298122/where-are-methods-stored-in-memory – M.kazem Akhgary Feb 09 '18 at 16:44

3 Answers3

7

Methods don't have a type. Methods are what they are - just "callable functions" on an object or class. The fact that you can assign them to Delegates or Func with same signature is just a feature of the framework, but the method on itself doesn't have any "type".

The closest thing to a type could be the return value of the method (if it has one).

Martin Zikmund
  • 38,440
  • 7
  • 70
  • 91
  • Could you review my summarization please? it's at on the end of the question. – Kangjun Heo Feb 09 '18 at 16:56
  • 1
    `Delegate` types and `Func<...>` are actually types. But methods themselves have no type, although they can be represent an "instance" of these types when the method signature matches the delegate signature. – Martin Zikmund Feb 09 '18 at 16:59
4

A method is not an object therefore it has no type.

A method in C# is the object oriented way of attaching functions to classes, but they are not first class citizens as functions are in JavaScript.

That's why you cannot assign a method to a variable.

You can't do this:

var func = Int32.Parse;

But instead you can do something like this:

Func<string, int> func2 = Int32.Parse;

In the second example despite the fact that it looks like you are actually assigning a method to a variable the reality is that the compiler creates a new instance of a Func<string, int> which is a delegate (which ultimately derives from System.Object) that happens to actually hold a type-safe reference to the method itself.

That delegate IS an object and can be assigned and passed as parameters to other methods, but is not the method itself but a wrapper.

Carlos Muñoz
  • 17,397
  • 7
  • 55
  • 80
  • It's funny how in one sentence you say we can't assign a method to a variable just to assign a method to a variable in the next line of your text. I can't see how the compiler creating a new instance of a delegate (variable) which will then be assigned to a method pointer could be stated as "this is not assigning a method to a variable" - this is literally what you are doing. What is the difference from assigning an object reference (or pointer in that sense) to a variable and assigning a function pointer to a variable? – underthevoid Jan 30 '21 at 19:37
  • A Delegate object is not a method pointer is an instance of a class. As I said before methods are not objects therefore cannot be assigned to variables. A func IS an object of an anonymous type that the compiler creates. You can use dotPeek or similar decompiler tool to actually see what the compiler creates for you. – Carlos Muñoz Jan 30 '21 at 19:48
  • A delegate is a class that serves the purpose of referencing methods - and that is done holding the method pointer inside a delegate. Also how is that any different than assigning an object reference to a variable? What the compiler does to compile the assignment of a method to a delegate variable does not change the fact that it is assigning a method to a variable (in the exact semantic way as an object reference is not a class pointer and yet have its pointer used by the compiler/CLR to reference itself under the hood). – underthevoid Jan 30 '21 at 19:59
3

All things are derived from System.Object, but not everything is a thing.

Object.GetType() explains:

"Because System.Object is the base class for all types in the .NET Framework type system, the GetType method can be used to return Type objects that represent all .NET Framework types. The .NET Framework recognizes the following five categories of types:

Classes, which are derived from System.Object,

Value types, which are derived from System.ValueType.

Interfaces, which are derived from System.Object starting with the .NET Framework 2.0.

Enumerations, which are derived from System.Enum.

Delegates, which are derived from System.MulticastDelegate."

An instance method is not one of those, it has no meaning apart from its class.

Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
Jens Fiederer
  • 420
  • 4
  • 7
  • Interfaces don't **derive** from anything. Try this: `typeof(System.Collections.IEnumerable).BaseType` it returns null – Carlos Muñoz Feb 09 '18 at 17:11
  • There is a whole item on that question at https://stackoverflow.com/questions/3236305/do-interfaces-derive-from-system-object-c-sharp-spec-says-yes-eric-says-no-re – Jens Fiederer Feb 09 '18 at 18:09
  • So while you are correct about BaseType, you CAN do typeof(System.Collections.IEnumerable).ToString() or typeof(System.Collections.IEnumerable).GetHashCode() and get expected result. Perhaps this is a bug rather than correct behavior, if you allow the spec to trump real life :-) – Jens Fiederer Feb 09 '18 at 18:16