没有实例C#的调用方法

时间:2016-04-20 09:29:49

标签: c#

我正在使用c#。
我上课了

class A
{
   public void MyMethod(int x){//Do something...};
}

如何在不创建MyMethod实例的情况下致电Class A? 我可以使用委托/行动或其他方式来做到这一点吗? *不将MyMethod更改为静态功能

由于

3 个答案:

答案 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作为参数的方法,因此调用该方法时thisnull

但是你绝对不应该这样做如果面试官真的希望你知道这一点,那么这更像是对你的反思而不是你的反思。

在实际实例上调用实例方法意图

答案 1 :(得分:3)

没有。实例方法需要调用实例。

实例方法主要有两个重要原因:

  1. 有权访问实例的成员(this
  2. 可选地,作为virtual(或接口)方法,从而允许实现符合给定接口,同时提供自己的具体实现
  3. 没有实例,这两者都是不可能的。如果您不需要,请使用您的方法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没有区分outref个参数。

    在与非C#代码进行互操作时,或在处理您正在执行的潜在恶意代码时,这一点非常重要 - 不要认为所有C#限制都适用于整个.NET。

答案 2 :(得分:0)

将其设为static,这样您就不需要实例化类来调用方法,因此类定义将是:

class A
{
   public static void MyMethod(int x){//Do something...};
}

这样您就可以像MyMethod

那样致电A.MyMethod(10);

对编辑的响应:如果不创建实例,则无法访问特定类的instance method,唯一的选择是将其设置为静态。