Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
553 views
in Technique[技术] by (71.8m points)

properties - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...