C#: acessando o Dicionário utilizando uma classe parcial

0

Pergunta

Estou tentando acessar um Dicionário da seguinte forma, usando uma classe parcial. A finalidade disso é para expor este dicionário e permitir que diferentes métodos diretamente de leitura/gravação de/para ele.

FilenameABC.cs tem esse código, o que parece estar OK para mim até agora:

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

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

FilenameDEF.cs tem esse código e este é o lugar onde eu estou tendo dificuldades. Eu não sou certo porque os .Adicionar métodos não funcionam. No primeiro, eu estou tentando usá-lo apenas após a criação de uma instância da ExampleDictionary de classe, que parece ser bastante contra-intuitivo (dado o meu nível atual de conhecimento, é claro). Na segunda, eu estou a tentar adicionar elementos a partir de dentro de um método, que é

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

Alguém poderia ajudar, por favor?

2
1

O método estático FunctionA não é possível acessar membros de instância de ClassA.

Alterar FunctionA a não ser estático ou faça o dicionário campo estático.

2021-11-22 16:28:57
1

Eu ainda não consegue dizer o que você está tentando fazer. Mas eu vou fazer o meu melhor para mostrar-lhe algumas coisas.

Eu estou tomando esta frase que você escreveu: "A finalidade dessa é a de expor este dicionário e permitir que diferentes métodos diretamente de leitura/gravação de/para ele." como meu guia

Classe Parcial Questões

Como mencionei nos comentários: não há tal coisa como uma Classe Parcial. A palavra-chave parcial simplesmente indica que uma classe pode ser definida em mais de um arquivo. A definição de regras para a classe continua a mesma, só que alguns dos membros da classe podem ser definidos em um arquivo e outras partes em outros arquivos.

Os problemas que você está tendo aqui tem nada a ver com o partial palavra-chave.

Os Dois // Isso não funcionar Notas

O primeiro se parece com isso:

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

A primeira linha declara o deputado, campo de ClassA chamado instanceOfDict e a inicializa. Por isso não compila.

A segunda linha tenta colocar runnable código (uma chamada de função) diretamente no nível superior do escopo de uma classe. Você não pode fazer isso. Você pode colocar um monte de coisas no nível superior escopo de uma classe (por exemplo, campos, propriedades, métodos, delegados, enums, classes internas), mas você não pode colocar o código lá.

O segundo problema parecido com este:

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

Funcional e br é um static o método. instanceOfDict é um campo particular da classe, não declarados como static. Você não pode referir-se a instância para a instância de nível de membros (métodos, propriedades, campos, ...) a partir de um método estático. Leia sobre o static palavra-chave.

A criação de uma Classe que, Seletivamente, Expõe um Dicionário

Já que você quer fazer algum dicionário de trabalho dentro de uma classe, mas expô-lo para o lado de fora, eu fui porco inteiro e fez da minha classe genérica em <TKey, TValue> assim que ele trabalha com Dicionários de qualquer tipo.

Eu também fiz isso implementar a Coleta de Inicialização Padrão para que você possa inicializar as instâncias da classe apenas como se fosse um dicionário.

Para usar a Coleção de Inicialização Padrão, a classe tem de fazer para as coisas:

  1. Implementar IEnumerable ou IEnumerable<T> (T pode ser qualquer tipo, não apenas o tipo que você está coletando - você pode até mesmo jogar uma NotImplementedException se você não se importa)

  2. Inclui um método que parece public void Add (SomeType atLeastOneParameter). Você pode ter mais de uma sobrecarga de Add se você desejar.

Então, eu começo com este (tenha em atenção que 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();
    }
}

Isso é o suficiente para tornar uma classe, principalmente, olhar como um dicionário (o que provavelmente deseja adicionar alguma forma, para obter os dados, etc. Mas, isso é com você (você provavelmente quer ter um indexador (em TKey) e uma TryGetValue.

Mas, vamos adicionar um pouco mais aleatório funcionalidade para a classe (colocar isso no nível superior escopo da classe):

    public int Count => _theDictionary.Count;

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

Que irá permitir que você veja quantas coisas estão no seu dicionário e permitir que você para iterar sobre os itens (a KeyValuePairs) que o Dicionário de coleções. Sinta-se livre para adicionar mais recursos.

Finalmente, para testar esse...

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 eu executar esse código, eu recebo:

TestDict Count: 6
one
five
eight
ten
hundredFive
threeHundred

Divisão esta usando Parcial

Eu não sei por que você deseja usar partial class. Normalmente isso é feito para ter dois blocos de código que são editados/mantidas por diferentes personas (o motivo típico é para o Visual Studio templating/mágico mecanismo para a manutenção de um lado do partial class e o programador a outros.

As regras são bastante simples, você simplesmente declarar public partial class MyClass em dois arquivos. Os dois arquivos devem estar no mesmo projeto (por exemplo, compilados no mesmo Assembly) e as classes devem estar no mesmo espaço de nomes. Depois de fazer isso, basta dividir os (nível superior escopo) bits e partes entre os dois partial class declarações.

Neste casos, eu provavelmente iria dividi-lo desta forma:

  • De um lado, eu ia colocar as duas funções necessárias para implementar o declarado IEnumerator<TValue>:
    • public IEnumerator<TValue> GetEnumerator()
    • IEnumerator IEnumerable.GetEnumerator()
  • De um outro lado, eu ia colocar tudo o resto:
    • O dicionário de declaração e inicialização
    • O outro enumerador: public IEnumerable<KeyValuePair<TKey, TValue>> GetKeyValuePairs()
    • public int Count => _theDictionary.Count;
    • public void Add(TKey key, TValue value)
2021-11-23 01:45:02

Eu não posso expressar o quanto sou grato por isso. Isso também me ajudou a quebrar alguns conceitos errados que eu tinha. Às vezes, aprender programação recebe uma frustrante no editor, felizmente existem incrível pessoas como você, que dedicam uma parte do seu dia para ajudar os outros. Obrigado novamente!
roccaforte

Sim, eu faço. Felizmente, tenho conseguido este emblema que me permite, como um recém-chegado, para iniciar a negociação de moeda. :-)
roccaforte

Em outros idiomas

Esta página está em outros idiomas

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