ルビーなどでは、既存の祖先クラスに新しいメソッドを追加することができ、すべての子孫が継承します。それがC#でも可能かどうかは疑問だ。C#スーパークラスにメソッドを追加することは可能ですか?
たとえば、Xamarin.FormsのPageクラスに、いくつかのメソッドを追加して、すべてのNavigationPages ContentPagesおよびPageの他の子孫で自動的に利用できるようにしたいとします。あなたはC#でそのようなことをすることはできますか?
ルビーなどでは、既存の祖先クラスに新しいメソッドを追加することができ、すべての子孫が継承します。それがC#でも可能かどうかは疑問だ。C#スーパークラスにメソッドを追加することは可能ですか?
たとえば、Xamarin.FormsのPageクラスに、いくつかのメソッドを追加して、すべてのNavigationPages ContentPagesおよびPageの他の子孫で自動的に利用できるようにしたいとします。あなたはC#でそのようなことをすることはできますか?
はい、ソートの、 "拡張メソッド" を用いて:
void Main()
{
var foo = new Foo();
Console.WriteLine(foo.GetDoubleBar());
}
public class Foo
{
public int Bar => 42;
}
// Defined somewhere else in your code
public static class FooEx
{
public static int GetDoubleBar(this Foo foo) => foo.Bar * 2;
}
static
クラスFooEx
でstatic
GetDoubleBar
でthis
キーワードが拡張メソッドを定義します。
これを実行すると、84
が出力されます。
はい実際には、拡張メソッドは、メソッドを含むように型のメタデータを拡張するので、C#に移動する方法です。最良の例はLinq to objects
であり、すべてのメソッドがIEnumerable<T>
の拡張子であるため、すべての子コレクションクラスで同様の処理に同じメソッドを使用することができます。標準形式は、最初のオブジェクトがthis
というキーワードでマークされた静的クラスの静的メソッドであり、これはコンパイラに拡張メソッドであることを伝え、次の例を取ると、文字列クラスContains
メソッドを拡張してそのケースを無視します。
public static class StringExtensions
{
public static bool Contains(this string source, string subString)
{
return source?.IndexOf(subString, StringComparison.OrdinalIgnoreCase) >= 0;
}
}
string
は、他のタイプの基底クラスであってもよいが、上記の例我々は.NET Frameworkの種類のすべての種類でそれを行うことができます示していないことができますが。
以下は、詳細についてはhereをチェックし、LINQのSelect
ためのコードです:
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector) {
if (source == null) throw Error.ArgumentNull("source");
if (selector == null) throw Error.ArgumentNull("selector");
return SelectIterator<TSource, TResult>(source, selector);
}
はい、ソートの、 "拡張メソッド" を使用することもできます。 – Enigmativity
ありがとうございました。私が拡張メソッドを利用したいすべてのモジュールに "using"節を置く必要があるのはやや面倒ですが、それはやっているようです。 – user1023110
@ user1023110 - 参照する必要のあるクラスに 'using'節を付ける必要がありません。 – Enigmativity