扩展方法如何工作?

我想在Unity3d中为Vector3类做一个扩展方法。 但我似乎不太明白。 这是我的:

public static class ExtensionMethods{ public static Vector3 MaxValue(this Vector3 _vec3) { return new Vector3(float.MaxValue,float.MaxValue,float.MaxValue); } } 

现在我想使用Vector3.MaxValue这个代码行来创build一个Vector3.MaxValue

 Vector3 closestPoint = Vector3.MaxValue; 

但是,然后我得到这个错误:

 error CS0117: `UnityEngine.Vector3' does not contain a definition for `MaxValue' 

我知道这将工作:

 Vector3 closestPoint = new Vector3().MaxValue(); 

但是,我创build了2个新的Vector3实例。 一个在MaxValue调用,一个在外面。 是不是可以做一个这样的代码:

 Vector3 closestPoint = Vector3.MaxValue; 

首先,这里是一个非常快速的教程扩展为那些学习c#/团结任何人在这里search:

创build一个新的文本文件HandyExtensions.cs像这样…(注意,有些令人困惑的是,你可以使用任何名字来保存你的扩展的类 – 这个类的实际名称根本不会被使用,无关紧要)…

  using UnityEngine; using System.Collections; using System.Collections.Generic; public static class HandyExtensions { public static float Jiggled(this float ff) { return ff * Random.Range(0.9f,1.1f); } } 

你现在已经做了一个新的“命令” Jiggle() 。 你可以在任何float上使用抖动。 看看它说“这个浮动 ff”。 因为它在那里说“浮动”,所以这个扩展在浮动上工作。

正如你所看到的, Jiggled()扩展将会浮动并稍微改变它。 像这样尝试

  float x = 3.5f; Debug.Log("x is " + x); Debug.Log("x is " + x.Jiggled() ); Debug.Log("x is " + x.Jiggled() ); Debug.Log("x is " + x.Jiggled() ); Debug.Log("x is " + x.Jiggled() ); Debug.Log("x is " + x.Jiggled() ); 

做一些这样的testing,直到你对扩展有一个很好的理解。 尽可能多地学习扩展! 这是另一个教程。

现在在这个页面上的问题! …


正如Mikael解释的那样,你所寻找的并不是一个扩展。 (另外请注意,如果你正在向Vector3 添加一个字段 ,你不能在c#中完成这个工作。)

现在,如果你想返回“那个东西”,你需要在前面join静态类名 ,而不要把它作为扩展名。 这只是一个正常的静态调用。

错误…

 public static Vector3 MaxValue(this Vector3 _vec3) { return new Vector3(float.MaxValue,float.MaxValue,float.MaxValue); } 

正确…

 public static Vector3 MaxValue() { return new Vector3(float.MaxValue,float.MaxValue,float.MaxValue); } 

你可以这样做…

 Debug.Log( ExtensionMethods.MaxValue() ); 

我想这可能是你在那里寻找的东西。

您通常会像Handy一样调用ExtensionMethods这样您就可以编写它了

  Handy.MaxValue(); 

事实上,既然你不能把“Vector3”放在前面,那么这样的事情就会更加清楚:

  Handy.MaxVector3(); 

说得通?

如果你想写这样的东西: Vector3.MaxValue()你不能这样做……因为“Vector3”部分是一个类 (或结构),而不是一个variables。 例如,这是一个整数的扩展:

  375.Jiggle(); 

这是一个整数的扩展:

  int x; x.Jiggle(); 

但这是没有意义的:

  int.Jiggle(); // meaningless 

为了清楚起见,请注意,您问:

我想在Unity3d中为Vector3类[实际上是一个结构]

扩展只能在实际variables上调用,而不能在“类或结构”上调用。

  Vector3 hero; Vector3 enemy; hero.Jiggle(); // works great enemy.Jiggle(); // works great Vector3.Jiggle(); // syntax error - meaningless 

还要注意,正如Mikael在他的回答中提到的那样,事实上你可以这样做:

  (new Vector3()).Jiggle(); 

如果你认为这也是有道理的。 在c#中我最喜欢的东西之一就是你可以在普通的旧常量上使用扩展:

  14.Jiggle(); 7.5f.Radians(); 

除非你从生活中得不到快乐,否则你一定要喜欢它。 这是一个例子:

 public static Color Colored( this float alpha, int r, int g, int b ) { return new Color( (float)r / 255f, (float)g / 255f, (float)b / 255f, alpha ); } 

然后你可以写。 Color c = .5f.Colored(.2f,.4f,.2f); 这是一个pupley颜色与0.5f的α。

我一直认为,如果你所问的语法是可用的 ,如果你可以有一个“types”或“类”作为你所扩展的“事物”,那么这将是非常好的,但事实并非如此。 对于你想要做的事情,你必须使用一个方便的词,例如,好的,这样做

Vector3 big = Handy.MaxVec3();

我希望这解释的情况!


再次对于任何需要一般介绍扩展, 介绍 。 这里是我最喜欢的扩展。

在每个游戏项目中都使用如下所示的内容…

 public static float Jiggle(this float ff) { return ff * UnityEngine.Random.Range(0.9f,1.1f); } public static float PositiveOrNegative(this float ff) { int r = UnityEngine.Random.Range(0,2); if (r==0) return ff; return -ff; } public static bool Sometimes(this int n) { if (n<=1) return true; int r = UnityEngine.Random.Range(0,n); return (r==0); } 

示例使用..

  if ( 10.Sometimes() ) { explode spaceship } 

它只做十次一次。

  if ( 3.Sometimes() ) { laser sparkle } 

在这个例子中,只有三分之一的时间。

(请注意,通常情况下,您会尽可能使扩展名使用generics,为简单起见,此处未显示。

这是一个方便的扩展技巧 。 这是一个非常高级的扩展 。

在Unity工程中,扩展是无处不在的。

如果你是使用Unity编程的许多人之一,那么你应该掌握的第一件事就是扩展。 尝试用延伸来做几乎所有事情 。 有时候使用Unity时,几乎每一行代码都需要一个或多个扩展。 请享用!

扩展方法是一种使静态方法成为类或接口的一部分的方式。 Vector3上的扩展方法Foo()意味着你可以像你说的那样做新的Vector3()。Foo()。

看起来你希望你的MaxValue属性是Vector3上的一个静态成员,而扩展方法不能帮你。 没有办法将静态成员添加到现有的类。

但是,真的有必要吗? 你可以在一个新的types中定义你的常量属性。 我们把它叫做“KnownVectors”或者什么的,去:

 Vector3 closestPoint = KnownVectors.MaxValue; 

当然,也许这会很好,不知道怎么把这个变成现有的Vector3类,但是它会真的给你的代码添加任何东西吗?