内置类型的运算符重载

内置类型的运算符重载

问题描述:

如何重写用于像String,数组等内建类型的运算符?例如:我希望覆盖数组的+运算符。内置类型的运算符重载

您不能重载现有类型的运算符,因为这可能会破坏使用该类型的任何其他代码。

您可以创建自己的类来封装数组,从数组中暴露出您需要的方法和属性,并重载任何有意义的运算符。

例子:

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

基本上你不能。

您可以使用扩展方法,这样添加功能:

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

但是,这并不与运营商合作。

+0

不宜用运营商在内建类型或扩展方法上重载? – Lennie 2009-03-06 09:26:53

+0

是的 - 即使你能做到这一点,也会导致代码非常混乱:“为什么这个阵列不像他们通常那样工作?” – Keith 2009-03-06 10:39:05

不能:)

但是,您可以在阵列例如从IEnnumerable或列表继承......和覆盖这些运营商。

简短的回答是你不能像@Keith指出的那样。

较长的答案是,如果要将运算符重载添加到类中,则需要能够更改该类的源代码。

在添加操作符来处理两种不同类型(例如数组+字符串)组合的情况下,您可以更改其中一种类型的源代码就足够了。这意味着你应该能够添加代码来指定如果你将一个自己的类型添加到数组中,会发生什么。

在BCL类的情况下,你运气不好。