Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Get property value without creating instance?

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.

like image 460
user1475694 Avatar asked Jun 22 '12 19:06

user1475694


2 Answers

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!)

like image 92
Jon Skeet Avatar answered Sep 18 '22 10:09

Jon Skeet


You can make that property static

public static string Name{ get{ return "David"; } }  

Usage:

MyClass.Name; 
like image 27
alexm Avatar answered Sep 17 '22 10:09

alexm