C# Get property value without creating instance?

user1475694 picture user1475694 · Jun 22, 2012 · Viewed 12.9k times · Source

Is it possible to get value without creating an instance ?

I have this class:

public class MyClass
{
    public string Name{ get{ return "David"; } }

    public MyClass()
    {
    }
}

Now I need get the value "David", without creating instance of MyClass.

Answer

Jon Skeet picture Jon Skeet · Jun 22, 2012

Real answer: no. It's an instance property, so you can only call it on an instance. You should either create an instance, or make the property static as shown in other answers.

See MSDN for more information about the difference between static and instance members.

Tongue-in-cheek but still correct answer:

Is it possible to get value without creating an instance ?

Yes, but only via some really horrible code which creates some IL passing in null as this (which you don't use in your property), using a DynamicMethod. Sample code:

// Jon Skeet explicitly disclaims any association with this horrible code.
// THIS CODE IS FOR FUN ONLY. USING IT WILL INCUR WAILING AND GNASHING OF TEETH.
using System;
using System.Reflection.Emit;

public class MyClass
{
    public string Name { get{ return "David"; } }
}


class Test    
{
    static void Main()
    {
        var method = typeof(MyClass).GetProperty("Name").GetGetMethod();
        var dynamicMethod = new DynamicMethod("Ugly", typeof(string), 
                                              Type.EmptyTypes);
        var generator = dynamicMethod.GetILGenerator();
        generator.Emit(OpCodes.Ldnull);
        generator.Emit(OpCodes.Call, method);
        generator.Emit(OpCodes.Ret);
        var ugly = (Func<string>) dynamicMethod.CreateDelegate(
                       typeof(Func<string>));
        Console.WriteLine(ugly());
    }
}

Please don't do this. Ever. It's ghastly. It should be trampled on, cut up into little bits, set on fire, then cut up again. Fun though, isn't it? ;)

This works because it's using call instead of callvirt. Normally the C# compiler would use a callvirt call even if it's not calling a virtual member because that gets null reference checking "for free" (as far as the IL stream is concerned). A non-virtual call like this doesn't check for nullity first, it just invokes the member. If you checked this within the property call, you'd find it's null.

EDIT: As noted by Chris Sinclair, you can do it more simply using an open delegate instance:

var method = typeof(MyClass).GetProperty("Name").GetGetMethod();
var openDelegate = (Func<MyClass, string>) Delegate.CreateDelegate
    (typeof(Func<MyClass, string>), method);
Console.WriteLine(openDelegate(null));

(But again, please don't!)