2009-11-26 3 views
4

Je voudrais créer ma propre classe qui étend le tableau d'ints. Est-ce possible? Ce dont j'ai besoin, c'est un tableau d'entiers qui peut être ajouté par un opérateur "+" à un autre tableau (chaque élément ajouté à chacun), et comparé par "==", de sorte qu'il pourrait (espérons-le) être utilisé comme clé dans le dictionnaire. Le fait est que je ne veux pas implémenter l'interface IList entière à ma nouvelle classe, mais seulement ajouter ces deux opérateurs à la classe de tableau existante.C# Étendre le type de tableau pour surcharger les opérateurs

Je suis en train de faire quelque chose comme ceci:

class MyArray : Array<int> 

Mais il ne fonctionne pas de cette façon évidemment;).

Désolé si je suis pas clair, mais je solution la recherche d'heures maintenant ...

MISE À JOUR:

J'ai essayé quelque chose comme ceci:

class Zmienne : IEquatable<Zmienne> 
{ 
    public int[] x; 
    public Zmienne(int ilosc) 
    { 
     x = new int[ilosc]; 
    } 
    public override bool Equals(object obj) 
    { 
     if (obj == null || GetType() != obj.GetType()) 
     { 
      return false; 
     } 
     return base.Equals((Zmienne)obj); 
    } 
    public bool Equals(Zmienne drugie) 
    { 
     if (x.Length != drugie.x.Length) 
      return false; 
     else 
     { 
      for (int i = 0; i < x.Length; i++) 
      { 
       if (x[i] != drugie.x[i]) 
        return false; 
      } 
     } 
     return true; 
    } 

    public override int GetHashCode() 
    { 
     int hash = x[0].GetHashCode(); 
     for (int i = 1; i < x.Length; i++) 
      hash = hash^x[i].GetHashCode(); 
     return hash; 
    } 

} 

utilise alors comme ça :

Zmienne tab1 = new Zmienne(2); 
Zmienne tab2 = new Zmienne(2); 
tab1.x[0] = 1; 
tab1.x[1] = 1; 

tab2.x[0] = 1; 
tab2.x[1] = 1; 

if (tab1 == tab2) 
    Console.WriteLine("Works!"); 

Et aucun effet. Je ne suis pas bon avec des interfaces et des méthodes prépondérants malheureusement :(Comme pour la raison que je suis en train de le faire, j'ai quelques équations comme:..

x1 + x2 = 0,45
x1 + x4 = 0,2
x2 + x4 = 0.11

Il y en a beaucoup plus, et je dois par exemple ajouter la première équation à la seconde et chercher toutes les autres pour savoir s'il y en a qui correspondent à la combinaison de x'es résultant de cette addition

Peut-être que je vais dans le mauvais sens?

Répondre

4

Pour un seul type, il est assez facile à résumer, comme ci-dessous. Notez que comme une clé que vous voulez le rendre immuable aussi. Si vous voulez utiliser des génériques, il devient plus difficile (demander plus d'informations):

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Text; 
static class Program { 
    static void Main() { 
     MyVector x = new MyVector(1, 2, 3), y = new MyVector(1, 2, 3), 
       z = new MyVector(4,5,6); 
     Console.WriteLine(x == y); // true 
     Console.WriteLine(x == z); // false 
     Console.WriteLine(object.Equals(x, y)); // true 
     Console.WriteLine(object.Equals(x, z)); // false 
     var comparer = EqualityComparer<MyVector>.Default; 
     Console.WriteLine(comparer.GetHashCode(x)); // should match y 
     Console.WriteLine(comparer.GetHashCode(y)); // should match x 
     Console.WriteLine(comparer.GetHashCode(z)); // *probably* different 
     Console.WriteLine(comparer.Equals(x,y)); // true 
     Console.WriteLine(comparer.Equals(x,z)); // false 
     MyVector sum = x + z; 
     Console.WriteLine(sum); 
    } 
} 
public sealed class MyVector : IEquatable<MyVector>, IEnumerable<int> { 
    private readonly int[] data; 
    public int this[int index] { 
     get { return data[index]; } 
    } 
    public MyVector(params int[] data) { 
     if (data == null) throw new ArgumentNullException("data"); 
     this.data = (int[])data.Clone(); 
    } 
    private int? hash; 
    public override int GetHashCode() { 
     if (hash == null) { 
      int result = 13; 
      for (int i = 0; i < data.Length; i++) { 
       result = (result * 7) + data[i]; 
      } 
      hash = result; 
     } 
     return hash.GetValueOrDefault(); 
    } 
    public int Length { get { return data.Length; } } 
    public IEnumerator<int> GetEnumerator() { 
     for (int i = 0; i < data.Length; i++) { 
      yield return data[i]; 
     } 
    } 
    IEnumerator IEnumerable.GetEnumerator() { 
     return GetEnumerator(); 
    } 
    public override bool Equals(object obj) 
    { 
     return this == (obj as MyVector); 
    } 
    public bool Equals(MyVector obj) { 
     return this == obj; 
    } 
    public override string ToString() { 
     StringBuilder sb = new StringBuilder("["); 
     if (data.Length > 0) sb.Append(data[0]); 
     for (int i = 1; i < data.Length; i++) { 
      sb.Append(',').Append(data[i]); 
     } 
     sb.Append(']'); 
     return sb.ToString(); 
    } 
    public static bool operator ==(MyVector x, MyVector y) { 
     if(ReferenceEquals(x,y)) return true; 
     if(ReferenceEquals(x,null) || ReferenceEquals(y,null)) return false; 
     if (x.hash.HasValue && y.hash.HasValue && // exploit known different hash 
      x.hash.GetValueOrDefault() != y.hash.GetValueOrDefault()) return false; 
     int[] xdata = x.data, ydata = y.data; 
     if(xdata.Length != ydata.Length) return false; 
     for(int i = 0 ; i < xdata.Length ; i++) { 
      if(xdata[i] != ydata[i]) return false; 
     } 
     return true;   
    } 
    public static bool operator != (MyVector x, MyVector y) { 
     return !(x==y); 
    } 
    public static MyVector operator +(MyVector x, MyVector y) { 
     if(x==null || y == null) throw new ArgumentNullException(); 
     int[] xdata = x.data, ydata = y.data; 
     if(xdata.Length != ydata.Length) throw new InvalidOperationException("Length mismatch"); 
     int[] result = new int[xdata.Length]; 
     for(int i = 0 ; i < xdata.Length ; i++) { 
      result[i] = xdata[i] + ydata[i]; 
     } 
     return new MyVector(result); 
    } 
} 
+0

Merci, je vais essayer ça :). – Episodex

+0

très bon point sur l'immutabilité – ShuggyCoUk

+0

Fonctionne maintenant, merci beaucoup! – Episodex

5

Son pas autorisés à étendre la classe de tableau, voir la référence: http://msdn.microsoft.com/en-us/library/system.array.aspx

Vous pouvez soit mettre en œuvre IList (qui a les méthodes de base) ou encapsulent un tableau dans votre classe et fournir aux opérateurs de conversion.

S'il vous plaît laissez-moi savoir si vous avez besoin de plus de détails.

+0

Je vais essayer d'encapsuler ensuite. Merci! – Episodex

+0

L'encapsulation est presque toujours préférable à l'héritage, en particulier lorsque vous souhaitez étendre un type de structure significatif. Notez également que l'implémentation de == ne fait PAS fonctionner un type dans un dictionnaire dans C# (f # est une question différente) vous devez implémenter IEquatable ou remplacer Equals (objet) ainsi que l'implémentation de GetHashCode() – ShuggyCoUk

+0

En fait, Marc a fait tout pour vous - utilise sa réponse :) – ShuggyCoUk

0

Ne pouvez-vous pas simplement utiliser la classe List? Cela fait déjà ce que vous voulez via la méthode AddRange.

+0

Je ne suis pas sûr s'il ne veut pas représenter de grands nombres de cette façon. – Grzenio

Questions connexes