C#での関数の書き方いくつか
1. 通常のメソッド
Unityでは通常、メソッドはMonoBehaviourを継承したクラス内で定義します。
using UnityEngine;
public class MethodExample : MonoBehaviour
{
void Start()
{
int result = Add(3, 5);
Debug.Log(result); // "8" が出力される
}
int Add(int a, int b) // インスタンスメソッド
{
return a + b;
}
}
2. メソッドのオーバーロード
Unityでもメソッドのオーバーロードを利用できます。
using UnityEngine;
public class OverloadExample : MonoBehaviour
{
void Start()
{
Debug.Log(Add(3, 5)); // "8" が出力される
Debug.Log(Add(3.5f, 5.5f)); // "9" が出力される
}
int Add(int a, int b) { return a + b; }
float Add(float a, float b) { return a + b; }
}
3. デフォルト引数
Unityでもメソッドにデフォルト引数を指定することができます。
using UnityEngine;
public class DefaultArgumentExample : MonoBehaviour
{
void Start()
{
Greet(); // "Hello, Guest!" が出力される
Greet("Alice"); // "Hello, Alice!" が出力される
}
void Greet(string name = "Guest")
{
Debug.Log("Hello, " + name + "!");
}
}
4. デリゲート(関数ポインタに相当)
Unityでデリゲートを使って、関数を動的に切り替えて呼び出すことができます。
using UnityEngine;
public class DelegateExample : MonoBehaviour
{
delegate int Operation(int a, int b); // デリゲート型を定義
Operation operation;
void Start()
{
operation = Add;
Debug.Log(operation(5, 3)); // "8" が出力される
operation = Multiply;
Debug.Log(operation(5, 3)); // "15" が出力される
}
int Add(int a, int b) { return a + b; }
int Multiply(int a, int b) { return a * b; }
}
5. ラムダ式(匿名関数)
ラムダ式を使って匿名関数を作成し、Unityでメソッド内に直接書くことができます。
using UnityEngine;
using System;
public class LambdaExample : MonoBehaviour
{
void Start()
{
Func<int, int, int> add = (a, b) => a + b;
Debug.Log(add(3, 5)); // "8" が出力される
}
}
6. インターフェースメソッドと抽象メソッド
C#のインターフェースと抽象メソッドを使うことで、Unityでも仮想関数のようなメソッドのオーバーライドが可能です。
using UnityEngine;
public class InterfaceExample : MonoBehaviour
{
void Start()
{
Animal animal = new Dog();
animal.Speak(); // "Woof" が出力される
}
}
abstract class Animal
{
public abstract void Speak(); // 抽象メソッド
}
class Dog : Animal
{
public override void Speak()
{
Debug.Log("Woof");
}
}
7. ジェネリックメソッド
Unityでもジェネリックメソッドを使って、異なる型に対応したメソッドを定義することができます。
using UnityEngine;
public class GenericExample : MonoBehaviour
{
void Start()
{
Debug.Log(Add(3, 5)); // "8" が出力される
Debug.Log(Add(3.5f, 5.5f));// "9" が出力される
}
T Add<T>(T a, T b) where T : struct //T が値型(構造体)であることを制約しています。これにより、int や float などの値型しか受け取れません
{
dynamic x = a, y = b; //dynamic 型は、コンパイル時に型チェックを行わず、実行時に型が決まります
return x + y;
}
}
8. ローカル関数
以下のコードでは、Addメソッド内にローカル関数LocalAddが定義されています。LocalAddはAddメソッド内でしか呼び出せず、処理がAddメソッドに閉じ込められています。
using UnityEngine;
public class LocalFunctionExample : MonoBehaviour
{
void Start()
{
Debug.Log(Add(3, 5)); // "8" が出力される
}
int Add(int a, int b)
{
int LocalAdd(int x, int y) // ローカル関数
{
return x + y;
}
return LocalAdd(a, b);
}
}
9. インラインメソッドの最適化
C#には直接のインライン指定はありませんが、MethodImplOptions.AggressiveInlining属性を使って最適化のインライン化を促せます。
ただ、C#のインライン化はJITコンパイラ次第なので、AggressiveInliningを指定しても、インライン化されないことがあります。また、コードが複雑すぎる場合や大きすぎる場合には、逆にパフォーマンスが低下する可能性もあるため、むやみに使わず、使うならパフォーマンス検証を行いながら使う必要があります。
using UnityEngine;
using System.Runtime.CompilerServices;
public class InlineExample : MonoBehaviour
{
void Start()
{
Debug.Log(Add(3, 5)); // "8" が出力される
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
int Add(int a, int b)
{
return a + b;
}
}