扩展方法如何工作?
我想在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类,但是它会真的给你的代码添加任何东西吗?