2009-11-06 2 views
7

Что не так с этим кодом на C#? Я попытался перегрузить оператор +, чтобы добавить два массива, но получил сообщение об ошибке следующим образом:Перегрузка оператора + для добавления двух массивов

Одним из параметров двоичного оператора должен быть содержащийся тип.

class Program 
{ 
    public static void Main(string[] args) 
    { 
     const int n = 5; 

     int[] a = new int[n] { 1, 2, 3, 4, 5 }; 
     int[] b = new int[n] { 5, 4, 3, 2, 1 }; 
     int[] c = new int[n]; 

     // c = Add(a, b); 
     c = a + b; 

     for (int i = 0; i < c.Length; i++) 
     { 
     Console.Write("{0} ", c[i]); 
     } 

     Console.WriteLine(); 
    } 

    public static int[] operator+(int[] x, int[] y) 
    // public static int[] Add(int[] x, int[] y) 
    { 
     int[] z = new int[x.Length]; 

     for (int i = 0; i < x.Length; i++) 
     { 
     z[i] = x[i] + y[i]; 
     } 

     return (z); 
    } 
} 
+0

На странице MSDN по перегрузке есть дополнительная информация - http://msdn.microsoft.com/en-us/library/aa288467%28VS.71%29.aspx – ChrisF

+0

Мы рассматриваем возможность добавления операторов расширения к гипотетической будущую версию C#, которая решит вашу проблему. Опрос соломы: у любого из вас есть УДИВИТЕЛЬНЫЕ сценарии для этой функции? Более удивительные сценарии REALISTIC, которые мы можем получить, тем более вероятно, что функция будет реализована в один прекрасный день. Отправляй мне свой путь; вы можете использовать ссылку по электронной почте в своем блоге. –

+0

Спасибо Эрик.Означает ли это, что мы также получим «Расширение всего» :) –

ответ

16

Операторы должны быть объявлены внутри тела «родственного» класса. Например:

public class Foo 
{ 
    int X; 

    // Legal 
    public static int operator+(int x, Foo y); 

    // This is not 
    public static int operator+(int x, int y); 
} 

Поскольку у вас нет доступа к реализации массивов, лучше всего было бы либо обернуть массивы в вашей собственной реализации, так что вы можете предоставить дополнительные операции (и это единственный способ ., чтобы оператор + работа

с другой стороны, вы могли бы определить метод расширения как:

public static class ArrayHelper 
{ 
    public static int[] Add(this int[] x, int[] y) { ... } 
} 

Воли еще приведет к естественным вызовам (x.Add(y)), избегая при этом, чтобы обернуть массивы в своем собственном классе.

1

Если вы хотите перегружать ле оператор + между типа АА и ВВ, вы должны сделать это в классе АА или ВВ, а не в классе с именем программы (как вы это делали).

К несчастью, вы не можете написать код в массиве класс.

Что вы можете сделать, это

  • создать свой собственный класс, который реализует IList
  • и поставить оператор + в этом классе.

Если вам нужна более подробная реализация, просто спросите меня.

+0

Слишком плохо, что класс не может реализовать 'this [int]' таким образом, чтобы соответствовать поведению подстроки массива (возвращая значение 'byref', а не значение). – supercat

2

Его состояние указывает, что один из параметров для оператора должен быть того же типа, что и операторская функция. Поэтому, если операторная функция является членом MyClass on, параметры должны быть типа MyClass.

class MyClass 
{ 
... 

public static int[] operator+(MyClass x, int[] y) 
    // public static int[] Add(int[] x, int[] y) 
    { 
     int[] z = new int[x.Length]; 

     for (int i = 0; i < x.Length; i++) 
     { 
     z[i] = x[i] + y[i]; 
     } 

     return (z); 
    } 
} 
1

Вы можете добавлять операторов только к типу, который вы создаете самостоятельно. A int[] - это встроенный тип, к которому вы не можете добавить операторов.

Вы можете создать свой собственный класс, который инкапсулирует массив и добавить к нему оператор.

2

Вы можете использовать что-то вроде этого:

class Program { 
    static void Main(string[] args) { 
    const int n = 5; 

    var a = new int[n] { 1, 2, 3, 4, 5 }.WithOperators(); 
    var b = new int[n] { 5, 4, 3, 2, 1 }; 

    int[] c = a + b; 

    for (int i = 0; i < c.Length; i++) { 
     Console.Write("{0} ", c[i]); 
    } 

    Console.WriteLine(); 
    } 
} 

public static class Int32ArrayExtensions { 
    public static Int32ArrayWithOperators WithOperators(this int[] self) { 
    return self; 
    } 
} 

public class Int32ArrayWithOperators { 
    int[] _array; 

    public Int32ArrayWithOperators(int[] array) { 
    if (array == null) throw new ArgumentNullException("array"); 
    _array = array; 
    } 

    public static implicit operator Int32ArrayWithOperators(int[] array) { 
    return new Int32ArrayWithOperators(array); 
    } 
    public static implicit operator int[](Int32ArrayWithOperators wrapper) { 
    return wrapper._array; 
    } 

    public static Int32ArrayWithOperators operator +(Int32ArrayWithOperators left, Int32ArrayWithOperators right) { 
    var x = left._array; 
    var y = right._array; 
    return x.Zip(y, (a, b) => a + b).ToArray(); 
    } 
} 

Основываясь на родственном post, что я написал.

Смежные вопросы