【发布时间】:2009-03-06 09:12:39
【问题描述】:
如何覆盖运算符以用于字符串、数组等内置类型?例如:我希望覆盖数组 + 运算符的含义。
【问题讨论】:
标签: c#
如何覆盖运算符以用于字符串、数组等内置类型?例如:我希望覆盖数组 + 运算符的含义。
【问题讨论】:
标签: c#
基本上你不能。
您可以使用扩展方法来添加如下功能:
public void CustomAdd( this Array input, Array addTo ) {
...
}
但这不适用于运营商。
【讨论】:
您不能为现有类型重载运算符,因为这可能会破坏使用这些类型的任何其他代码。
您可以创建自己的类来封装数组,从数组中公开您需要的方法和属性,并重载任何有意义的运算符。
例子:
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 等扩展方法。)
【讨论】:
你不能:)
但是,对于数组示例,您可以从 IEnnumerable 或 List ... 继承并覆盖这些运算符。
【讨论】:
正如@Keith 指出的那样,简短的回答是你不能。
更长的答案是,要为类添加运算符重载,您需要能够更改该类的源代码。
在添加运算符来处理两种不同类型(例如数组 + 字符串)的组合的情况下,您可以更改其中一种类型的源代码就足够了。这意味着您应该能够添加代码来指定如果您将自己的一种类型添加到数组中会发生什么。
在 BCL 类的情况下,你运气不好。
【讨论】: