繁体   English   中英

扩展方法如何工作?

[英]How do extension methods work?

我想在Unity3d中为Vector3类创建一个扩展方法。 但是我似乎不太明白。 这就是我所拥有的:

public static class ExtensionMethods{

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

现在,我想使用以下代码行来制作一个与Vector3.MaxValue一样的float.MaxValue

Vector3 closestPoint = Vector3.MaxValue;

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

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

我知道这会起作用:

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

但是,然后我创建了两个新的Vector3实例。 一个在MaxValue调用中,一个在外部。 用这样的代码编写一个代码是不可能的:

Vector3 closestPoint = Vector3.MaxValue;

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

像这样创建一个新的文本文件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上使用微动。 看到它说“ this float ff”的地方。 由于该扩展名仅在此处显示“ float”,因此该扩展程序适用于float。

如您所见, 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() );

像这样进行一些测试,直到您对扩展有了很好的了解。 尽可能多地了解扩展! 这是另一个教程。

现在,此页面上的问题! ...


正如Mikael解释的那样,您要寻找的实际上不是扩展。 (还请注意,如果您尝试向Vector3 添加字段 ,则无法在c#中执行此操作。)

现在,如果要返回“那个东西”,则需要在前面包含静态类名 ,而不必将其扩展。 这只是对static的普通调用。

错误...

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()  );

我认为那可能是您在那寻找的东西。

通常,您可以将ExtensionMethods称为Handy之类的简短名称,以便编写

 Handy.MaxValue();

实际上,由于您不能将“ Vector3”放在前面,因此类似以下内容会更清楚:

  Handy.MaxVector3();

说得通?

如果您尝试编写如下代码: Vector3.MaxValue() ,则无法执行此操作,因为“ Vector3”部分是CLASS (或Struct),而不是变量。 例如,这是整数的扩展:

 375.Jiggle();

这是整数的扩展:

 int x;
 x.Jiggle();

但这是没有意义的:

 int.Jiggle();  // meaningless

为了清楚起见,请重复以下步骤:

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

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

   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); 这是具有0.5f的alpha的浅绿色。

我一直认为,如果您所要求的语法可用 ,并且可以像扩展您的“东西”一样拥有“类型”或“类”,那就太好了,但事实并非如此。 对于您想做的事情,您只需要使用一个方便的单词,例如,好用,就可以了

Vector3 big = Handy.MaxVec3();

我希望这可以解释情况!


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

每个游戏项目中都使用类似以下内容的东西:

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
   }

在该示例中,它只执行大约三分之一的时间。

(请注意,实际上,通常您会在可能的情况下使扩展使用泛型。为简单起见,此处未显示。)

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

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

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

扩展方法是一种使其看起来像静态方法是类或接口的一部分的方法。 Vector3的扩展方法Foo()意味着您可以像说的那样创建新的Vector3()。Foo()。

您似乎希望MaxValue属性成为Vector3上的静态成员,而扩展方法无法为您提供帮助。 无法将静态成员添加到现有类。

但是,真的有必要吗? 您可以只在新类型中定义常量属性。 让我们称之为“ KnownVectors”之类,然后去:

Vector3 closestPoint = KnownVectors.MaxValue;

当然,以某种方式将它塞入现有的Vector3类中可能会很好,但是会真的在代码中添加任何内容吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM