C#: accesso Dizionario con un parziale di classe

0

Domanda

Sto cercando di accedere a un Dizionario nel modo seguente, utilizzando un parziale di classe. Il fine di questo è quello di esporre questo dizionario e permettono diversi metodi direttamente in lettura/scrittura da/per esso.

FilenameABC.cs ha questo codice, che sembra essere OK per me finora:

namespace Namespace1
{
    partial class ClassA
    {
        public class ExampleDictionary
        {
            private Dictionary<int, string> _dict;

            public ExampleDictionary()
            {
                _dict = new Dictionary<int, string>();
            }
        }
    }
}

FilenameDEF.cs ha questo codice e questo è dove sto avendo difficoltà. Io non sono sicuro perché l' .Aggiungere i metodi non funzionano. Nel primo sto cercando di usarlo solo dopo la creazione di un'istanza del ExampleDictionary classe, che sembra essere abbastanza intuitivo (dato il mio livello di conoscenza attuale, ovviamente). Nel secondo, invece, sto cercando di aggiungere elementi all'interno di un metodo, che è

namespace Namespace1
{
    partial class ClassA
    {
        ExampleDictionary instanceOfDict = new ExampleDictionary();
        instanceOfDict.Add(1, "Test1"); // This does not work

        public static void FunctionA()
        {            
            for (int i = 0; i < 10; i++)
            {
            string text = $"Test{i}";
            instanceOfDict.Add(i, text); // This does not work as well              
            }          
        }
    }
}

Chiunque potrebbe aiutare, per favore?

2
1

Il metodo statico FunctionA non possono accedere i membri di istanza di ClassA.

Cambiare FunctionA per non essere statici o il dizionario di campo statico.

2021-11-22 16:28:57
1

Io ancora non riesco a dire ciò che si sta cercando di fare. Ma farò del mio meglio per mostrare un po ' di roba.

Sto prendendo questa frase che hai scritto: "Lo scopo finale di questo è quello di esporre questo dizionario e permettono diversi metodi direttamente in lettura/scrittura da/per farlo." come la mia guida

Parziale Classe Di Problemi

Come ho detto nei commenti: non c'è nessuna tale cosa come un Parziale di Classe. La parola chiave parziale, semplicemente indica che una classe può essere definita in uno o più file. La definizione di regole per la classe di rimanere lo stesso, è solo che alcuni membri della classe può essere definita in un file e di altre parti in altri file.

I problemi si verificano qui hanno nulla a che fare con il partial parola chiave.

I tuoi Due // Questo non funziona Note

Il primo assomiglia a questo:

partial class ClassA
{
    ExampleDictionary instanceOfDict = new ExampleDictionary();
    instanceOfDict.Add(1, "Test1"); // This does not work
    //other code
}

La prima riga dichiara membro privato campo di ClassA nome instanceOfDict e la inizializza. Ecco perché si compila.

La seconda linea cerca di mettere in esecuzione il codice (una chiamata di funzione) direttamente nell'ambito di primo livello di una classe. Non si può fare. Si può mettere un po ' di cose al livello superiore ambito di una classe (ad esempio, i campi, le proprietà, i metodi, i delegati, le enumerazioni, classi interne), ma non si può mettere il codice non c'.

Il secondo problema simile a questo:

public static void FunctionA()
{            
    for (int i = 0; i < 10; i++)
    {
        string text = $"Test{i}";
        instanceOfDict.Add(i, text); // This does not work as well              
    }          
}

Funzionali è un static metodo. instanceOfDict è un campo privato della classe, non dichiarata come statico. Non è possibile fare riferimento ad esempio a livello di istanza membri (metodi, proprietà, campi, ...) da un metodo statico. Leggere su static parola chiave.

La creazione di una Classe che Espone in modo Selettivo un Dizionario

Dal momento che si vuole fare qualche dizionario di lavorare all'interno di una classe, ma esporre verso l'esterno, sono andato fino in fondo e ha reso la mia classe generico su <TKey, TValue> in modo che funziona con i Dizionari di qualsiasi tipo.

Ho anche fatto implementare la Raccolta di Inizializzazione del Modello in modo che è possibile inizializzare le istanze della classe come un dizionario.

Per utilizzare la Collezione di Inizializzazione del Modello, la classe deve fare di cose:

  1. Implementare IEnumerable o IEnumerable<T> (T può essere di qualsiasi tipo, non solo per il tipo di raccolta - si può anche buttare un NotImplementedException se non si cura)

  2. Include un metodo che sembra public void Add (SomeType atLeastOneParameter). Si può avere più di un sovraccarico di Add se lo si desidera.

Allora, inizio con questa (Notare che implementa IEnumerable<T>:

public partial class TestExposedDictionary<TKey, TValue> : IEnumerable<TValue>
{
    private readonly Dictionary<TKey, TValue> _theDictionary = new Dictionary<TKey, TValue>();

    public void Add(TKey key, TValue value)
    {
        _theDictionary.Add(key, value);
    }

    public IEnumerator<TValue> GetEnumerator()
    {
        foreach (var kvp in _theDictionary)
        {
            yield return kvp.Value;
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

Che è abbastanza per fare una classe per lo più l'aspetto di un dizionario (vostra, probabilmente vuole aggiungere qualche modo per ottenere i dati, etc. Ma, ecco a voi (probabilmente si desidera avere un indicizzatore (su TKey) e un TryGetValue.

Ma, aggiungiamo un po ' di più casuale funzionalità di classe (mettere questo al livello superiore ambito della classe):

    public int Count => _theDictionary.Count;

    public IEnumerable<KeyValuePair<TKey, TValue>> GetKeyValuePairs()
    {
        foreach (var kvp in _theDictionary)
        {
            yield return kvp;
        }
    }

Che vi permetterà di vedere quante cose ci sono nel tuo dizionario e consentono di scorrere gli elementi (il KeyValuePairs) che il Dizionario collezioni. Sentitevi liberi di aggiungere ulteriori funzionalità.

Infine, per verificare questo...

public static void Test()
{
    var testDict = new TestExposedDictionary<int, string> {
        {1, "one" },
        {5, "five" },
        {8, "eight" },
        {10, "ten" },
        {105, "hundredFive" },
    };

    // I can call Add in the normal way as well:
    testDict.Add(300, "threeHundred");

    Console.WriteLine($"TestDict Count: {testDict.Count}");
    foreach (string s in testDict)
    {
        Console.WriteLine(s);
    }
}

Quando eseguo questo codice ottengo:

TestDict Count: 6
one
five
eight
ten
hundredFive
threeHundred

Dividere questo con Parziale

Non so perché si desidera utilizzare partial class. Normalmente questo viene fatto di avere due pezzi di codice che vengono modificati/mantenuto da diverse persone (il tipico motivo è per Visual Studio dei template/magico meccanismo per mantenere un lato della partial class e il programmatore gli altri.

Le regole sono abbastanza semplici, è sufficiente dichiarare public partial class MyClass in due file. I due file devono essere nella stessa azione (ossia, compilato nella stessa Assemblea) e le classi devono essere nello stesso spazio dei nomi. Una volta fatto questo, basta dividere la (ambito di primo livello) di bit e pezzi tra i due partial class dichiarazioni.

In questi casi, probabilmente sarei diviso in questo modo:

  • Se da un lato si, avevo messo le due funzioni necessarie per attuare il dichiarato IEnumerator<TValue>:
    • public IEnumerator<TValue> GetEnumerator()
    • IEnumerator IEnumerable.GetEnumerator()
  • Dall'altra parte, mi piacerebbe mettere tutto il resto:
    • Il dizionario dichiarazione e intialization
    • L'altro enumeratore: public IEnumerable<KeyValuePair<TKey, TValue>> GetKeyValuePairs()
    • public int Count => _theDictionary.Count;
    • public void Add(TKey key, TValue value)
2021-11-23 01:45:02

Non posso esprimere quanto sono grato per questo. Questo mi ha anche aiutato a rompere un paio di idee sbagliate che ho avuto. A volte imparare a programmare ottiene un ma frustrante, ma per fortuna ci sono splendide persone come voi, che dedicano una parte della giornata per aiutare gli altri. Grazie ancora!
roccaforte

Sì, lo faccio. Fortunatamente, ho appena ottenuto il badge che consente di me come un nuovo arrivato per iniziare a fare trading di valuta. :-)
roccaforte

In altre lingue

Questa pagina è in altre lingue

Русский
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................