扩展方法如何工作? [英] How do extension methods work?

查看:31
本文介绍了扩展方法如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to make an extension method in Unity3d for the Vector3 class. But I don't quite seem to get it. This is what I have:

public static class ExtensionMethods{

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

现在我想用这行代码制作一个 Vector3.MaxValue 就像 float.MaxValue 一样:

Now I want to make a Vector3.MaxValue just like float.MaxValue with this line of code:

Vector3 closestPoint = Vector3.MaxValue;

但后来我收到此错误:

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

我知道这行得通:

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

但后来我创建了 2 个新的 Vector3 实例.一个在 MaxValue 调用中,一个在外部.是不是可以只制作一个并使用这种代码来做:

But then I create 2 new Vector3 instances. One in the MaxValue call and one outside. Isn't it possible to just make one and do it with this kind of code:

Vector3 closestPoint = Vector3.MaxValue;

推荐答案

首先,这里有一个非常快速的扩展教程,适用于学习 c#/Unity 的任何人在这里谷歌搜索:

First, here's a very quick tutorial on extensions for those learning c#/Unity for anyone googling here:

像这样创建一个新的文本文件 HandyExtensions.cs ...(请注意,这有点令人困惑,您可以对持有"的类使用任何名称; 您的扩展名 - 类的实际名称根本没有使用过,并且是无关紧要的)...

Make a new text file HandyExtensions.cs like this ... (note that somewhat confusingly, you can use any name at all for the class which "holds" your extensions - the actual name of the class is never used at all, and is irrelevant) ...

 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 上使用 jiggle.看看它在哪里说this float ff".因为它说浮动"就在那里,这个扩展适用于浮动.

You have now made a new "command" Jiggle(). You can use jiggle on any float. See where it says "this float ff". Because it says "float" just there, this extension works on floats.

如您所见,Jiggled() 扩展将采用浮点数并稍作更改.像这样试试

As you can see, the Jiggled() extension will take a float and change it slightly. Try it like this

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

做一些类似的测试,直到你对扩展有了很好的理解.尽可能多地了解扩展!这是另一个教程.

Do some tests like that until you have a good understanding of extensions. Learn as much as you can about extensions! Here's another tutorial.

正如 Mikael 解释的那样,您要查找的实际上并不是扩展程序.(另请注意,如果您尝试向 Vector3 添加字段,则不能在 c# 中这样做.)

As Mikael explains, what you are looking for is not actually an extension. (Also note, if you're trying to add a field to Vector3, you cannot do that in c#.)

现在,如果你想返回那个东西"您需要在前面包含静态类名,并且不要将其作为扩展名.这只是对静态的正常调用.

Now, if you want to return "that thing" you need to include the static class name up front, and you DO NOT make it an extension. It's just a normal call to a 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);
}

然后你可以这样做......

you can then do this ...

Debug.Log(   ExtensionMethods.MaxValue()  );

我认为这可能就是您在那里寻找的东西.

I think that may be what you're looking for there.

您通常会调用ExtensionMethods 类似Handy 的简短名称,以便您可以编写

You'd normally call ExtensionMethods something short like Handy so you can write

 Handy.MaxValue();

确实,因为你不能把Vector3 放在前面",这样的事情会更清楚:

indeed, since you can't put the "Vector3 up front", something like this would be more clear:

  Handy.MaxVector3();

有意义吗?

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

If you're trying to write something like this: Vector3.MaxValue() you can't do that ... because the "Vector3" part IS A CLASS (or Struct), not a variable. For example, this is an extension on an integer:

 375.Jiggle();

这是一个整数的扩展:

 int x;
 x.Jiggle();

但这毫无意义:

 int.Jiggle();  // meaningless

为了清楚起见,请注意您提出的问题:

To repeat for clarity, note that you asked:

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

I want to make an extension method in Unity3d for the Vector3 class [actually a struct]

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

extensions can only be called on actual variables, not on "the class or struct".

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

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

Note too that as Mikael actually mentions in his answer, you can in fact actually do this:

  (new Vector3()).Jiggle();

如果你仔细想想,那也是有道理的.我在 c# 中最喜欢的事情之一是您可以在普通的旧常量上使用扩展:

If you think about it that makes sense, too. One of my favorite things in c# is that you can use extensions on plain old constants:

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

除非你从生活中得不到乐趣,否则你必须喜欢它.下面是一个例子:

You've got to love that unless you just get no pleasure from life. Here's an example of that:

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); 这是一种 alpha 为 .5f 的深褐色.

You can then write .. Color c = .5f.Colored(.2f,.4f,.2f); and that is a pucey color with an alpha of .5f.

我一直认为,如果你询问的语法可用,如果你能有一个类型"或类"以某种方式作为事物"你继续扩展 - 但事实并非如此.对于你想要做的事情,你只需要使用一个方便的词,比如,好,方便,然后做这个

I've always thought it would be great if the syntax you ask about was available, if you could have a "type" or "class" somehow as the "thing" you extend on - but it's not the case. For what you are trying to do, you have to just use a handy word such as, well, Handy, and do this

Vector3 big = Handy.MaxVec3();

Vector3 big = Handy.MaxVec3();

我希望这可以解释情况!

I hope this explains the situation!

对于需要扩展的一般介绍的任何人,介绍.以下是我最喜欢的一些扩展程序.

Again for anyone needing a general intro to extensions, intro. Here are some of my favorite extensions.

在每个游戏项目中都使用类似以下内容...

Something like the following is used in every game project...

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
   }

在那个例子中,它只执行了大约三分之一的时间.

in that example it only does it about a third of the time.

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

(Note that indeed typically you make extensions use generics where possible. Not shown here for simplicity.)

这是一个方便的扩展技巧.这是一个真正的高级扩展.

Here's a handy extension trick. Here's a really advanced extension.

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

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

If you are one of the many folks learning to code using Unity...pretty much the first thing you should master is extensions. Try to do almost everything with an extension. Sometimes when working with Unity, almost every line of code needs one or more extensions. Enjoy!

这篇关于扩展方法如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆