繁体   English   中英

c#中私有静态方法的用法是什么?

[英]What is the usage of private static method in c#?

我有一个名为MyClass.cs的公共类。 它有3种方法:

 public class MyClass
 {
    public IEnumerable<MyDto> PublicA(bool useCache = true)
    {
    //Call an external resource
    //some code
    }

    public IEnumerable<AnotherDto> PublicB()
    {
    //some code
    var x= MyPrivateMethod(input);
    //some code
    }

    private IEnumerable<AnotherDto> MyPrivateMethod(IEnumerable<SomeDto>)
    {
    //return Mapped data from IEnumerable<SomeDto> to  IEnumerable<AnotherDto>

    }
 }

我使用ReSharper作为重构工具。 它建议对MyPrivateMethod使用static

private static IEnumerable<AnotherDto> MyPrivateMethod(IEnumerable<SomeDto>)

但是这个关键字的用法是什么? 由于该方法是私有的,因此不会在其他想要使用MyClass实例的类中使用。

我测试并发现,当我为MyPrivateMethod使用static关键字时,我无法调用非私有静态的类的任何其他方法。 但我还不知道用法是什么? 例如,存储或时间优化是否有任何好处?

根据MSDN

不访问实例数据或调用实例方法的成员可以标记为static(在Visual Basic中为Shared)。 将方法标记为静态后,编译器将向这些成员发出非虚拟调用站点。 发出非虚拟调用站点将阻止在运行时检查每个调用,以确保当前对象指针为非null。 这可以为性能敏感的代码实现可测量的性能增益。 在某些情况下,无法访问当前对象实例表示正确性问题。

https://msdn.microsoft.com/en-us/library/ms245046.aspx

另一个好处是调用序列,当您调用实例方法时,生成的代码会this实例作为第一个参数推送到堆栈,并且该方法的其余参数将被推送到堆栈。 所以,每一个实例方法调用需要一个以上额外压栈this在沿有其他方法参数。

如果将方法转换为静态方法,则静态方法调用不需要this因此可以减少对CPU的推送操作。 单次通话似乎没什么大不了的。

但是,如果您的方法将被频繁使用,并且如果您有几种方法不需要this那么它可以节省大量的CPU时间,尤其是在图形和科学计算中。

这是什么原因Resharper是在暗示你改变的方法静态方法的时候没有引用任何的一部分this

这是样本,

    public int Add(int a, int b) {
        return a + b;
    }

    public static int StaticAdd(int a, int b) {
        return a + b;
    }

    public void InstanceAdd() {
        Console.WriteLine(this.Add(3,3));
    }

    public void InstanceAddStatic()
    {
        Console.WriteLine(StaticAdd(3, 3));
    }

这是为了在“InstanceAdd”中调用实例方法而生成的

.method public hidebysig 
    instance void InstanceAdd () cil managed 
{
    // Method begins at RVA 0x2095
    // Code size 16 (0x10)
    .maxstack 8

    IL_0000: nop
    IL_0001: ldarg.0
    IL_0002: ldc.i4.3
    IL_0003: ldc.i4.3
    IL_0004: call instance int32 Temp.MathTest::Add(int32, int32)
    IL_0009: call void [System.Console]System.Console::WriteLine(int32)
    IL_000e: nop
    IL_000f: ret
} // end of method MathTest::InstanceAdd

这是在“StaticAdd”中为例如方法生成的il

.method public hidebysig 
    instance void InstanceAddStatic () cil managed 
{
    // Method begins at RVA 0x20a6
    // Code size 15 (0xf)
    .maxstack 8

    IL_0000: nop
    IL_0001: ldc.i4.3
    IL_0002: ldc.i4.3
    IL_0003: call int32 Temp.MathTest::StaticAdd(int32, int32)
    IL_0008: call void [System.Console]System.Console::WriteLine(int32)
    IL_000d: nop
    IL_000e: ret
} // end of method MathTest::InstanceAddStatic

如果你看“StaticAdd”,就没有ldarg.0 ,就是this 对于每个方法调用,总会有ldarg.0作为第一条指令,然后其余的参数将会跟随。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM