扩展方法如何工作?

Mik*_*ink 0 c# extension-methods unity-game-engine

我想在Unity3d中为Vector3类创建一个扩展方法.但我似乎没有得到它.这就是我所拥有的:

public static class ExtensionMethods{

    public static Vector3 MaxValue(this Vector3 _vec3)
    {
        return new Vector3(float.MaxValue,float.MaxValue,float.MaxValue);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我想打一个Vector3.MaxValue,就像float.MaxValue用这行代码:

Vector3 closestPoint = Vector3.MaxValue;
Run Code Online (Sandbox Code Playgroud)

但后来我得到了这个错误:

error CS0117: `UnityEngine.Vector3' does not contain a definition for `MaxValue'
Run Code Online (Sandbox Code Playgroud)

我知道这会奏效:

Vector3 closestPoint = new Vector3().MaxValue();
Run Code Online (Sandbox Code Playgroud)

但后来我创建了2个新Vector3实例.一个在MaxValue通话中,一个在外面.是不是可以只使用这种代码制作一个并执行此操作:

Vector3 closestPoint = Vector3.MaxValue;
Run Code Online (Sandbox Code Playgroud)

Fat*_*tie 8

首先,这里有一个关于那些学习c#/ Unity的扩展的非常快速的教程,这里有人在Google上搜索:

制作一个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);
         }
     }
Run Code Online (Sandbox Code Playgroud)

你现在已经做了一个新的"命令" Jiggle().你可以在任何一个上使用微动float.看看它的"this 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() );
Run Code Online (Sandbox Code Playgroud)

在你对扩展有一个很好的理解之前做一些这样的测试.尽可能多地了解扩展!这是另一个教程.

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


正如Mikael所解释的那样,你所寻找的并不是一个延伸.(另请注意,如果您尝试向Vector3 添加字段,则无法在c#中执行此操作.)

现在,如果你想返回"那个东西",你需要预先包含静态类名,而不要把它作为扩展名.这只是对静态的正常调用.

错误...

public static Vector3 MaxValue(this Vector3 _vec3)
{
    return new Vector3(float.MaxValue,float.MaxValue,float.MaxValue);
}
Run Code Online (Sandbox Code Playgroud)

正确...

public static Vector3 MaxValue()
{
    return new Vector3(float.MaxValue,float.MaxValue,float.MaxValue);
}
Run Code Online (Sandbox Code Playgroud)

你可以这样做......

Debug.Log(   ExtensionMethods.MaxValue()  );
Run Code Online (Sandbox Code Playgroud)

我想那可能就是你在那里寻找的东西.

通常你会打电话来ExtensionMethods的东西一样短Handy,所以你可以写

 Handy.MaxValue();
Run Code Online (Sandbox Code Playgroud)

事实上,既然你不能把"Vector3放在前面",这样的事情会更清楚:

  Handy.MaxVector3();
Run Code Online (Sandbox Code Playgroud)

说得通?

如果你试图写这样的东西: Vector3.MaxValue()你不能这样做......因为"Vector3"部分是一个类(或结构),而不是一个变量.例如,这是整数的扩展名:

 375.Jiggle();
Run Code Online (Sandbox Code Playgroud)

这是整数的扩展:

 int x;
 x.Jiggle();
Run Code Online (Sandbox Code Playgroud)

但这没有意义:

 int.Jiggle();  // meaningless
Run Code Online (Sandbox Code Playgroud)

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

我想在Unity3d中为Vector3类创建一个扩展方法[实际上是一个结构]

扩展只能在实际变量上调用,而不能在"类或结构"上调用.

   Vector3 hero;
   Vector3 enemy;
   hero.Jiggle();  // works great
   enemy.Jiggle();  // works great

   Vector3.Jiggle();  // syntax error - meaningless
Run Code Online (Sandbox Code Playgroud)

另请注意,正如Mikael在答案中提到的那样,事实上你实际上可以这样做:

  (new Vector3()).Jiggle();
Run Code Online (Sandbox Code Playgroud)

如果你认为它也有意义.在c#中我最喜欢的一件事是你可以在普通旧常量上使用扩展:

 14.Jiggle();
 7.5f.Radians();
Run Code Online (Sandbox Code Playgroud)

除非你从生活中获得快乐,否则你必须要爱它.这是一个例子:

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 );
    }
Run Code Online (Sandbox Code Playgroud)

然后你可以写.. Color c = .5f.Colored(.2f,.4f,.2f);这是一个alpha值为.5f的pucey颜色.

我一直认为,如果您提出的语法可用,如果您可以将某种"类型"或"类"视为您延伸的"事物",那将会很棒- 但实际情况并非如此.对于你想要做的事情,你必须使用一个方便的词,比如,好吧,Handy,并且这样做

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);
    }
Run Code Online (Sandbox Code Playgroud)

示例用途..

 if ( 10.Sometimes() )
   {
   explode spaceship
   }
Run Code Online (Sandbox Code Playgroud)

它只进行十次.

 if ( 3.Sometimes() )
   {
   laser sparkle
   }
Run Code Online (Sandbox Code Playgroud)

在那个例子中,它只在大约三分之一的时间内完成.

(请注意,通常情况下,您可以在可能的情况下使用泛型.为简单起见,此处未显示.)

这是一个方便的扩展技巧.这是一个非常先进的扩展.

扩展在Unity工程中无处不在.

如果你是学习使用Unity编码的众多人之一......你应该掌握的第一件事就是扩展.尝试使用扩展程序做几乎所有事情.有时在使用Unity时,几乎每行代码都需要一个或多个扩展.请享用!