Domanda

Vorrei creare la mia classe estendendo l'array di ints. È possibile? Ciò di cui ho bisogno è una matrice di ints che può essere aggiunta da " + " operatore a un altro array (ogni elemento aggiunto a ciascuno) e confrontato con " == " ;, quindi potrebbe (si spera) essere usato come chiave nel dizionario.

Il fatto è che non voglio implementare l'intera interfaccia IList nella mia nuova classe, ma aggiungere solo questi due operatori alla classe di array esistente.

Sto cercando di fare qualcosa del genere:

class MyArray : Array<int>

Ma ovviamente non funziona in questo modo;).

Scusami se non sono chiaro ma sto cercando una soluzione da ore ...

UPDATE:

Ho provato qualcosa del genere:

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;
    }

}

Quindi usalo in questo modo:

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!");

E nessun effetto. Purtroppo non sono bravo con le interfacce e i metodi di sostituzione :(. Per quanto riguarda la ragione, sto provando a farlo. Ho alcune equazioni come:

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

Ce ne sono molti di più, e ad esempio ho bisogno di aggiungere la prima equazione alla seconda e cercare tutti gli altri per scoprire se ce n'è uno che corrisponde alla combinazione di x che risulta in quell'aggiunta.

Forse sto andando nella direzione totalmente sbagliata?

È stato utile?

Soluzione

Per un singolo tipo, è abbastanza facile da incapsulare, come di seguito. Nota che come chiave vuoi renderlo anche immutabile. Se vuoi usare i generici, diventa più difficile (chiedi maggiori informazioni):

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);
    }
}

Altri suggerimenti

Non è consentito estendere la classe array, consultare il riferimento: http : //msdn.microsoft.com/en-us/library/system.array.aspx

Puoi implementare IList (che ha i metodi di base) o incapsulare un array nella tua classe e fornire operatori di conversione.

Per favore fatemi sapere se avete bisogno di maggiori dettagli.

Non puoi semplicemente usare la classe List? Questo fa già quello che vuoi tramite il metodo AddRange.

scroll top