2009-03-06 26 views
2

String、配列などの組み込み型で使用する演算子をオーバーライドするにはどうすればよいですか?たとえば、配列の+演算子の指定をオーバーライドしたいとします。組み込み型の演算子オーバーロード

答えて

0

既存の型の演算子をオーバーロードすると、型を使用する他のコードが破損する可能性があります。

配列をカプセル化し、必要なメソッドとプロパティを配列から公開し、理にかなった演算子をオーバーロードする独自のクラスを作成できます。

例:

public class AddableArray<T> : IEnumerable<T> { 

    private T[] _array; 

    public AddableArray(int len) { 
     _array = new T[len]; 
    } 

    public AddableArray(params T[] values) : this((IEnumerable<T>)values) {} 

    public AddableArray(IEnumerable<T> values) { 
     int len; 
     if (values is ICollection<T>) { 
      len = ((ICollection<T>)values).Count; 
     } else { 
      len = values.Count(); 
     } 
     _array = new T[len]; 
     int pos = 0; 
     foreach (T value in values) { 
      _array[pos] = value; 
      pos++; 
     } 
    } 

    public int Length { get { return _array.Length; } } 

    public T this[int index] { 
     get { return _array[index]; } 
     set { _array[index] = value; } 
    } 

    public static AddableArray<T> operator +(AddableArray<T> a1, AddableArray<T> a2) { 
     int len1 = a1.Length; 
     int len2 = a2.Length; 
     AddableArray<T> result = new AddableArray<T>(len1 + len2); 
     for (int i = 0; i < len1; i++) { 
      result[i] = a1[i]; 
     } 
     for (int i = 0; i < len2; i++) { 
      result[len1 + i] = a2[i]; 
     } 
     return result; 
    } 

    public IEnumerator<T> GetEnumerator() { 
     foreach (T value in _array) { 
      yield return value; 
     } 
    } 

    IEnumerator System.Collections.IEnumerable.GetEnumerator() { 
     return _array.GetEnumerator(); 
    } 

} 

使用法:

// create two arrays 
AddableArray<int> a1 = new AddableArray<int>(1, 2, 3); 
AddableArray<int> a2 = new AddableArray<int>(4, 5, 6); 

// add them 
AddableArray<int> result = a1 + a2; 

// display the result 
Console.WriteLine(string.Join(", ", result.Select(n=>n.ToString()).ToArray())); 

(クラスがIEnumerable<T>を実装して、あなたがそれにSelectのような拡張メソッドを使用できることに注意してください。)

+0

これはa1 + a2 =統一された配列なので、ちょっとしたコードです。なぜa1.Union(a2).ToArray()を実行するだけでいいのですか。 – Keith

+0

はい、ずっと簡単ですが、効率的ではありません。しかし、それはかなり良いですが、クイックテストでは約2〜4倍の時間しかかかりません。 – Guffa

4

基本的にはできません。

次のような機能を追加する拡張メソッドを使用することができます。

public void CustomAdd(this Array input, Array addTo) { 
    ... 
} 

をしかし、これは事業者では動作しません。

+0

演算子を使うべきではありません組み込み型や拡張メソッドのオーバーロード – Lennie

+0

はい - これを行うことができたとしても、「この配列は通常のように機能しないのはなぜですか?」という非常に混乱したコードになります。 – Keith

1

あなたはしかし、配列例えば... IEnnumerableまたは一覧から継承し、それらの演算子を上書きすることができ

:)をすることはできません。

1

短い答えは、@Keithが指摘したとおり、できないということです。

答えは、クラスに演算子のオーバーロードを追加するには、そのクラスのソースコードを変更できる必要があります。

2つの異なる型(array + stringなど)の組み合わせを処理する演算子を追加する場合は、これらの型のいずれかのソースコードを変更するだけで十分です。つまり、独自の型のいずれかを配列に追加すると何が起こるかを指定するコードを追加できるはずです。

BCLクラスの場合、あなたは不運です。

関連する問題