真正的答案:没有。它是一个 instance 属性,因此您只能在实例上调用它。您应该创建一个实例,或者将属性设为静态,如其他答案所示。
有关静态成员和实例成员之间区别的更多信息,请参阅MSDN。
面面相觑,但仍然正确答案:
是否可以不创建实例而获得价值?
是的,但只能通过一些非常可怕的代码创建一些 IL 传递 null 作为 this(您不会在您的财产中使用),使用 DynamicMethod。示例代码:
// 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());
}
}
请不要这样做。 曾经。太可怕了。它应该被践踏,切成小块,点燃,然后再次切割。不过很有趣,不是吗? ;)
之所以有效,是因为它使用的是call 而不是callvirt。通常 C# 编译器会使用 callvirt 调用 即使它没有调用虚拟成员,因为它会“免费”进行空引用检查(就 IL 流而言)。像这样的非虚拟调用不首先检查无效性,它只是调用成员。如果你在属性调用中检查了this,你会发现它是空的。
编辑:正如 Chris Sinclair 所指出的,您可以使用开放的委托实例更简单地做到这一点:
var method = typeof(MyClass).GetProperty("Name").GetGetMethod();
var openDelegate = (Func<MyClass, string>) Delegate.CreateDelegate
(typeof(Func<MyClass, string>), method);
Console.WriteLine(openDelegate(null));
(但同样,请不要!)