C# 使用私有静态方法的优势
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/135020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Advantages to Using Private Static Methods
提问by NerdFury
When creating a class that has internal private methods, usually to reduce code duplication, that don't require the use of any instance fields, are there performance or memory advantages to declaring the method as static?
当创建一个具有内部私有方法的类时,通常是为了减少代码重复,不需要使用任何实例字段,将方法声明为静态是否有性能或内存优势?
Example:
例子:
foreach (XmlElement element in xmlDoc.DocumentElement.SelectNodes("sample"))
{
string first = GetInnerXml(element, ".//first");
string second = GetInnerXml(element, ".//second");
string third = GetInnerXml(element, ".//third");
}
...
...
private static string GetInnerXml(XmlElement element, string nodeName)
{
return GetInnerXml(element, nodeName, null);
}
private static string GetInnerXml(XmlElement element, string nodeName, string defaultValue)
{
XmlNode node = element.SelectSingleNode(nodeName);
return node == null ? defaultValue : node.InnerXml;
}
Is there any advantage to declaring the GetInnerXml() methods as static? No opinion responses please, I have an opinion.
将 GetInnerXml() 方法声明为静态方法有什么好处吗?没有意见请回复,我有意见。
采纳答案by Scott Dorman
From the FxCop rule pageon this:
来自FxCop 规则页面:
After you mark the methods as static, the compiler will emit non-virtual call sites to these members. Emitting non-virtual call sites will prevent a check at runtime for each call that ensures that the current object pointer is non-null. This can result in a measurable performance gain for performance-sensitive code. In some cases, the failure to access the current object instance represents a correctness issue.
将方法标记为静态后,编译器将向这些成员发出非虚拟调用站点。发出非虚拟调用站点将阻止在运行时对每个调用进行检查,以确保当前对象指针为非空。这可以为对性能敏感的代码带来可测量的性能提升。在某些情况下,无法访问当前对象实例表示正确性问题。
回答by Kent Boogaart
Yes, the compiler does not need to pass the implicit this
pointer to static
methods. Even if you don't use it in your instance method, it is still being passed.
是的,编译器不需要将隐式this
指针传递给static
方法。即使您不在实例方法中使用它,它仍然会被传递。
回答by Joel Coehoorn
This forces you to remember to also declare any class-scoped members the function uses as static as well, which should save the memory of creating those items for each instance.
这迫使您记住还要将函数使用的任何类作用域成员声明为静态成员,这样可以节省为每个实例创建这些项目的内存。
回答by Free Wildebeest
It'll be slightly quicker as there is no this parameter passed (although the performance cost of calling the method is probably considerably more than this saving).
由于没有传递这个参数,它会稍微快一点(尽管调用该方法的性能成本可能比这个节省的要多得多)。
I'd say the best reason I can think of for private static methods is that it means you can't accidentally change the object (as there's no this pointer).
我想说我能想到的私有静态方法的最好理由是这意味着你不能不小心更改对象(因为没有 this 指针)。
回答by Neil
When I'm writing a class, most methods fall into two categories:
当我编写一个类时,大多数方法分为两类:
- Methods that use/change the current instance's state.
- Helper methods that don't use/change the current object's state, but help me compute values I need elsewhere.
- 使用/更改当前实例状态的方法。
- 不使用/更改当前对象状态但帮助我计算其他地方需要的值的辅助方法。
Static methods are useful, because just by looking at its signature, you know that the calling it doesn't use or modify the current instance's state.
静态方法很有用,因为仅通过查看其签名,您就知道调用它不会使用或修改当前实例的状态。
Take this example:
拿这个例子:
public class Library { private static Book findBook(List<Book> books, string title) { // code goes here } }
If an instance of library's state ever gets screwed up, and I'm trying to figure out why, I can rule out findBook as the culprit, just from its signature.
如果图书馆状态的一个实例被搞砸了,而我正试图找出原因,我可以排除 findBook 作为罪魁祸首,仅凭其签名。
I try to communicate as much as I can with a method or function's signature, and this is an excellent way to do that.
我尝试尽可能多地与方法或函数的签名进行交流,这是一种很好的方式。
回答by Marek Takac
A call to a static method generates a call instruction in Microsoft intermediate language (MSIL), whereas a call to an instance method generates a callvirt instruction, which also checks for a null object references. However, most of the time the performance difference between the two is not significant.
对静态方法的调用会生成 Microsoft 中间语言 (MSIL) 中的调用指令,而对实例方法的调用会生成 callvirt 指令,该指令还会检查空对象引用。但是,大多数时候两者之间的性能差异并不显着。
src: MSDN - http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.110).aspx
源代码:MSDN - http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.110).aspx
回答by sara
I very much prefer all private methods to be static unless they really can't be. I would much prefer the following:
我非常喜欢所有私有方法都是静态的,除非它们真的不能。我更喜欢以下内容:
public class MyClass
{
private readonly MyDependency _dependency;
public MyClass(MyDependency dependency)
{
_dependency = dependency;
}
public int CalculateHardStuff()
{
var intermediate = StepOne(_dependency);
return StepTwo(intermediate);
}
private static int StepOne(MyDependency dependency)
{
return dependency.GetFirst3Primes().Sum();
}
private static int StepTwo(int intermediate)
{
return (intermediate + 5)/4;
}
}
public class MyDependency
{
public IEnumerable<int> GetFirst3Primes()
{
yield return 2;
yield return 3;
yield return 5;
}
}
over every method accessing the instance field. Why is this? Because as this process of calculating becomes more complex and the class ends up with 15 private helper methods, then I REALLY want to be able to pull them out into a new class that encapsulates a subset of the steps in a semantically meaningful way.
在访问实例字段的每个方法上。为什么是这样?因为随着这个计算过程变得越来越复杂,并且类最终有 15 个私有辅助方法,所以我真的希望能够将它们提取到一个新类中,该类以语义上有意义的方式封装步骤的子集。
When MyClass
gets more dependencies because we need logging and also need to notify a web service (please excuse the cliche examples), then it's really helpful to easily see what methods have which dependencies.
当MyClass
因为我们需要日志记录并且还需要通知 Web 服务而获得更多依赖项时(请原谅陈词滥调的示例),那么轻松查看哪些方法具有哪些依赖项真的很有帮助。
Tools like R# lets you extract a class from a set of private static methods in a few keystrokes. Try doing it when all private helper methods are tightly coupled to the instance field and you'll see it can be quite a headache.
像 R# 这样的工具可以让您通过几次按键从一组私有静态方法中提取一个类。当所有私有辅助方法都与实例字段紧密耦合时尝试这样做,您会发现这可能会令人头疼。
回答by James Haumann
As has already been stated, there are many advantages to static methods. However; keep in mind that they will live on the heap for the life of the application. I recently spent a day tracking down a memory leak in a Windows Service... the leak was caused by private static methods inside a class that implemented IDisposable and was consistently called from a using statement. Each time this class was created, memory was reserved on the heap for the static methods within the class, unfortunately, when the class was disposed of, the memory for the static methods was not released. This caused the memory footprint of this service to consume the available memory of the server within a couple of days with predictable results.
如前所述,静态方法有很多优点。然而; 请记住,它们将在应用程序的整个生命周期中都存在于堆中。我最近花了一天时间跟踪 Windows 服务中的内存泄漏……泄漏是由实现 IDisposable 的类中的私有静态方法引起的,并且始终从 using 语句中调用。每次创建这个类时,都会在堆上为类内的静态方法保留内存,不幸的是,当类被释放时,静态方法的内存并没有释放。这导致此服务的内存占用在几天内消耗了服务器的可用内存,结果可预测。