我正在使用c#。
我上课了
class A
{
public void MyMethod(int x){//Do something...};
}
如何在不创建MyMethod
实例的情况下致电Class A
?
我可以使用委托/行动或其他方式来做到这一点吗?
*不将MyMethod更改为静态功能
由于
答案 0 :(得分:10)
你可以这样做......但你真的,真的不应该这样做:
// DO NOT USE THIS CODE
using System;
public class Evil
{
public void Method()
{
Console.WriteLine($"Is this null? {this == null}");
}
}
class Test
{
static void Main()
{
var method = typeof(Evil).GetMethod("Method");
var action = (Action<Evil>) Delegate.CreateDelegate(typeof(Action<Evil>), method);
action(null);
}
}
输出:
Is this null? True
CreateDelegate
调用会创建一个打开的实例委托。来自MSDN:
在.NET Framework 2.0版中,此方法重载也可以创建开放实例方法委托;也就是说,明确提供实例方法隐藏的第一个参数的委托。有关详细说明,请参阅更一般的CreateDelegate(Type,Object,MethodInfo)方法重载,它允许您为实例或静态方法创建打开或关闭委托的所有组合,并可选择指定第一个参数。
然后我们调用传递null
作为参数的方法,因此调用该方法时this
为null
。
但是你绝对不应该这样做如果面试官真的希望你知道这一点,那么这更像是对你的反思而不是你的反思。
在实际实例上调用实例方法意图。
答案 1 :(得分:3)
没有。实例方法需要调用实例。
实例方法主要有两个重要原因:
this
)virtual
(或接口)方法,从而允许实现符合给定接口,同时提供自己的具体实现没有实例,这两者都是不可能的。如果您不需要,请使用您的方法static
。
修改强>
正如Jon Skeet所说,可能这样做。我隐约记得有一些这样奇怪的情况,但是我自己无法复制它,所以我认为它根本无法用于某种原因而无法工作。结果我在我的样本中犯了一个愚蠢的错误:)
但请注意,即便如此,使用实例方法的原因还是#34;上面仍然坚持 - 它不允许你做static
方法不会做任何事情。事实上,扩展方法恰恰是假装成实例方法的静态方法。例如。他们只是明确声明了this
参数。
与扩展方法不同,我认为这种方法不是真正的C#&#34;。您正在访问方法,就好像它不是C#方法一样。我并不认为这与使用C#编写IL以使用null
&#34;实例&#34;来调用方法有根本的不同:
ldnull
call instance void NS.A::MyMethod()
(当然翻译为ILGenerator.Emit
)
或者,就此而言,使用C#将几个字节写入内存,将它们移动到可执行页面并执行。
真正重要的部分是理解.NET和IL 不关心关于this
。它并不存在于IL中,它是C#概念(当然也用于其他语言),而C#有目的地限制了在方法中使用this
获得某些好处的能力。但是其他语言可能完全废除这样的东西,或使用不同的约定而不是&#34;实例方法的第一个参数是对对象实例的引用&#34;。还有很多其他类似的例子 - 例如IL没有区分out
和ref
个参数。
在与非C#代码进行互操作时,或在处理您正在执行的潜在恶意代码时,这一点非常重要 - 不要认为所有C#限制都适用于整个.NET。
答案 2 :(得分:0)
将其设为static
,这样您就不需要实例化类来调用方法,因此类定义将是:
class A
{
public static void MyMethod(int x){//Do something...};
}
这样您就可以像MyMethod
A.MyMethod(10);
对编辑的响应:如果不创建实例,则无法访问特定类的instance method
,唯一的选择是将其设置为静态。