Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C中的静态方法与实例方法#_C#_.net_Garbage Collection_Clr_Methods - Fatal编程技术网

C# C中的静态方法与实例方法#

C# C中的静态方法与实例方法#,c#,.net,garbage-collection,clr,methods,C#,.net,Garbage Collection,Clr,Methods,对于我正在编写的应用程序,我希望具有极端的可扩展性,扩展方法似乎能满足我的需要,并且能够在没有实例的情况下调用它们,这也是我所需要的 我记得读到过静态方法比实例方法快,但没有得到GC的优势。这是正确的吗 除非我通过设计而不是速度找到更好的替代方案,否则我不太可能改变我的设计。但我还是想知道速度、GC等方面的差异 编辑:谢谢。更多信息:假设我们有一个Person类: class Person 其中可以有一个实例距离方法,如下所示: this.Distance (Person p) 这很好,但这

对于我正在编写的应用程序,我希望具有极端的可扩展性,扩展方法似乎能满足我的需要,并且能够在没有实例的情况下调用它们,这也是我所需要的

我记得读到过静态方法比实例方法快,但没有得到GC的优势。这是正确的吗

除非我通过设计而不是速度找到更好的替代方案,否则我不太可能改变我的设计。但我还是想知道速度、GC等方面的差异

编辑:谢谢。更多信息:假设我们有一个Person类:

class Person
其中可以有一个实例距离方法,如下所示:

this.Distance (Person p)
这很好,但这并不能让我在不创建Person类实例的情况下计算两点之间的距离(比如点3)

我想做的是:

class Person (no Distance methods)
但距离的扩展方法:

Distance (this Person, Person)
Distance (this Point3, Point3)
这样我就可以做到:

myPerson.Distance (yourPerson)


EDIT2:@Jon,是的,我想这就是我的意思(不要利用GC的优势),但我不知怎么地认为静态方法会造成这种负担/开销。

在静态方法和实例方法之间进行选择是一个面向对象的设计问题。如果您正在编写的方法是对象的行为,那么它应该是实例方法。如果它不依赖于对象的实例,那么它应该是静态的

基本上,静态方法属于一种类型,而实例方法属于一种类型的实例。

你说的“没有GC的优势”是什么意思?方法不是垃圾收集的-实例是

虚拟方法比非虚拟方法稍微慢一点,我猜在任何实例方法之前都有令人讨厌的空检查,但这并不重要。选择最合适的设计

但是静态方法对于测试来说是一件痛苦的事情——例如,如果您通过调用某个静态方法在方法
Foo()
中进行身份验证,那么当您测试
Foo()
时,您不能让它只调用模拟身份验证程序(除非静态方法本身允许您这样做)。但是,如果您为正在测试的任何对象提供一个包含
Authenticate()
方法的某个接口的模拟实现的原始实例,则可以使其按您所需的方式运行


编辑:在这种情况下,听起来您真正需要的是
类型上的实例方法来计算两点之间的距离(“这一点和另一点”)——或者
距离
类型上的静态工厂方法。

如果速度越快意味着方法中的代码执行速度越快,那么不是。静态方法中的代码与非静态方法中的代码一样快

如果您正在谈论执行方法调用的开销,那么它会变得稍微复杂一些。对于Java这样的语言来说,实例调用的开销更大是很常见的。然而,在C#中,情况并非如此,因为实例方法在默认情况下不是虚拟的

因此,虚拟方法的开销略高于非虚拟方法。静态方法不能是虚拟的,但实例方法可以声明为虚拟的


至于垃圾收集,这主要与字段有关,而与方法无关。静态字段可以从代码中的任何地方访问,因此垃圾收集器无法确定引用是否将再次使用,因此它将永远不会被收集。

基于您的示例,我将编写一个静态实用程序函数来查找两点之间的距离:

public static class Geometry
{
    public static double GetDistanceBetween(Point a, Point b) { ... }
}
然后我会给这个人一个叫做Position的属性,它返回一个点。所以我可以写:

double distance = Geometry.GetDistanceBetween(personA.Position, personB.Position);
它实际上已经是用英语写的了——为什么要让它更晦涩呢?如果将距离作为一种方法,则可以编写:

personA.Distance(personB)
或:


这两种排序没有区别,但是使用方法调用语法表明可能有区别。

谢谢,是的,位置是我的Person类中的一个属性。但这些操作是由用户通过示意图构建的。所以我想有一个统一的方式来做这件事,但也有能力直接使用它们,而无需在UI中创建任何示意图项目。顺便说一句,我没有得到第二部分。你是说personA.Distance(personB)和Extensions.Distance是一样的?首先我让personA计算到personB的距离,然后我让personB计算到personA的距离。这两个人交换了。通过将其作为一种方法,你意味着这个人是在用自己独特的方式来理解它,这是误导性的。我建议不要添加距离方法我不知道用户构造操作是什么意思。你能在你的问题中再详细一点吗?谢谢。你是说我应该用静态距离法?还是说实例方法?另一件需要注意的事情是,我正在尝试使用LINQ风格的语法,比如person.A().B().C().D()…谢谢Jon。现在有意义了吗?谢谢,乔恩。我没有距离类型,因为它只是一个浮点数。例如,我不确定是否使用。我可以在Point中使用距离方法,但我也希望使用PointToRGBColor,但在我的设计中,这个RGB方法似乎也应该是扩展。现在这里的实例有100%的意义,就像RGB方法可以在Color类中一样。但如果必须有一个实例,这会阻止我直接使用该功能。就这点而言,这没关系,因为这是一个人必须使用的最基本的类型。嗯。。。我并没有真正理解Point/RGB示例。如果它只适用于某些上下文(而不是始终适用于任何情况下的任何用法),那么它作为扩展方法可能是有意义的。我建议不要过分使用扩展方法。这是否意味着对于客户对象来说,使用“GetAge()”这样的实例方法和“CustomerHelper.GetCustomerFromState(int-stateId)”这样的staticmethod是正确的方法?
GetAge
作为实例方法是有意义的。关于后者我不清楚
personA.Distance(personB)
personB.Distance(personA)