├── Data Structures ├── Lists │ ├── ArrayList │ │ ├── Implementation │ │ │ ├── MyArrayList.cs │ │ │ └── Program.cs │ │ └── README.md │ ├── LinkedList │ │ ├── Implementation │ │ │ ├── LinkedList.cs │ │ │ ├── Node.cs │ │ │ └── Program.cs │ │ ├── README.md │ │ ├── circular_linkedlist.webp │ │ ├── double_linkedlist.webp │ │ ├── linked_list.png │ │ └── single_linkedlist.webp │ └── README.md ├── README.md ├── Sets │ ├── HashSet │ │ ├── Implementation │ │ │ └── MyHashSet.cs │ │ └── README.md │ ├── README.md │ └── SortedSet │ │ ├── Implementation │ │ ├── MySortedSet.cs │ │ └── RedBlackTree.cs │ │ └── README.md └── interfaces_csharp.png ├── Design Patterns ├── Observer │ └── README.md ├── README.md └── Strategy │ ├── Calculadora.cs │ ├── ICMS.cs │ ├── ISS.cs │ ├── Imposto.cs │ ├── Orcamento.cs │ ├── Program.cs │ ├── README.md │ └── uml.png ├── ENTITY.md ├── INSTALLATION.md ├── MSTEST.md ├── NUGET.md ├── POWERSHELL.md ├── README.md ├── SOLID └── README.md ├── dump ├── Blog.cs ├── BloggingContext.cs ├── DatabaseMain.cs ├── Post.cs └── Primeiro.cs └── ps-cheatsheet.jpeg /Data Structures/Lists/ArrayList/Implementation/MyArrayList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace List 4 | { 5 | public class MyList 6 | { 7 | // Propriedade que guarda o tamanho do ArrayList 8 | private int size = 0; 9 | // Constante que guarda o tamanho máximo padrão da implementação 10 | private static readonly int DEFAULT_CAPACITY = 10; 11 | // Array de objetos onde os elementos serão colocados 12 | private Object[] elements; 13 | 14 | // Construtor 15 | public MyArrayList() 16 | { 17 | elements = new Object[DEFAULT_CAPACITY]; 18 | } 19 | 20 | // Método add 21 | // Des: Adiciona o elemento à ArrayList 22 | // Recebe: elemento (e) do tipo genérico 23 | // Retorna: void 24 | public void add(T e) 25 | { 26 | // se tamanho == nº de elementos, então aumente a capacidade 27 | if (size == elements.Length) 28 | { 29 | this.resize(); 30 | } 31 | // coloca e na posição de size++ (tamanho + 1) e seta o valor em size 32 | elements[size++] = e; 33 | } 34 | 35 | // Método resize 36 | // Des: Dobra o tamanho do ArrayList cada vez que o mesmo enche. 37 | // Recebe: void 38 | // Retorna: void 39 | public void resize() 40 | { 41 | int newSize = elements.Length * 2; 42 | // Aumenta o tamanho do array passado por referência pelo tamanho passado 43 | Array.Resize(ref elements, newSize); 44 | } 45 | 46 | // Método get 47 | // Des: Retorna os dados armazenados no indice passado 48 | // Recebe: indice (i) tipo inteiro 49 | // Retorna: elemento na posição i (element[i]) do tipo genérico 50 | public T get(int i) 51 | { 52 | if (i >= size || i < 0) 53 | { 54 | throw new System.IndexOutOfRangeException("Index: " + i + ", Size " + i ); 55 | } 56 | return (T) elements[i]; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Data Structures/Lists/ArrayList/Implementation/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ArrayList 4 | { 5 | class Program 6 | { 7 | static void Main(string[] args) 8 | { 9 | MyArrayList numeros = new MyArrayList(); 10 | numeros.add(5); 11 | numeros.add(15); 12 | numeros.add(89); 13 | numeros.add(24); 14 | numeros.add(789); 15 | numeros.add(963); 16 | numeros.add(856); 17 | numeros.add(753); 18 | numeros.add(7985); 19 | 20 | Console.WriteLine(numeros.get(0)); 21 | Console.WriteLine(numeros.get(1)); 22 | Console.WriteLine(numeros.get(2)); 23 | Console.WriteLine(numeros.get(6)); 24 | Console.WriteLine(numeros.get(7)); 25 | Console.WriteLine(numeros.get(8)); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Data Structures/Lists/ArrayList/README.md: -------------------------------------------------------------------------------- 1 | # List 2 | A Estrutura List (também conhecida como ArrayList) é uma estrutura de vetor com capacidade de dinamicamente alocar qualquer quantidade de Objetos. Ela surgiu para facilitar a criação de coleções de uma forma mais inteligente do que é feito pelos arrays nativos, utilizando-se da Orientação à Objetos para utilizar-se de métodos que facilitem a manipulação dos dados contidos no array. Por exemplo, se quisessemos adicionar um elemeto em um índice no meio do array, precisariámos inseri-lo e então reordenar todos os elementos posteriores, porém uma estrutura de List bem implemntada cuida disso para nós quando utilizamos o método **.add(** *Object o* **)**, também podemos utilizar o método **.get(** *int index* **)** para pegar o Objeto guardado na posição do índice. Além disso como dito anteriormente, o List pode implementar alguns métodos de manipulação, a implementação padrão utiliza [estes](https://docs.microsoft.com/pt-br/dotnet/api/system.collections.generic.list-1?view=netframework-4.8#m%C3%A9todos). 3 | 4 |

5 | 6 |

7 | 8 | ## Implementação básica em C# 9 | - [MyArrayList.cs](https://github.com/Camilotk/aprendendo_csharp/blob/master/Data%20Structures/Lists/ArrayList/Implementation/MyArrayList.cs) 10 | 11 | ### Propriedades 12 | O List possui três propriedades, uma que guarda o tamanho do List (*size*), uma constante que guarda a quantidade padrão de itens (capacidade, DEFAULT_CAPACITY) e um Array nativo que é instanciado no construtor com o tamanho padrão. 13 | ```C# 14 | private int size = 0; 15 | private static readonly int DEFAULT_CAPACITY = 10; 16 | private Object[] elements; 17 | ``` 18 | ### Método Add 19 | A implementação do método **.Add(** *Object o* **)** recebe o objeto do tipo genérico declarado quando a classe é criada, a vantagem de utlizar tipos genéricos ao invés de Object é que quando o método recebe um objeto acontece a checagem se o tipo do objeto é o mesmo declarado na classe. 20 | 21 | **Linhas 3-6** 22 | ```C# 23 | namespace List 24 | { 25 | public class MyList 26 | { 27 | ``` 28 | **Linhas 24-33** 29 | ```C# 30 | public void add(T e) 31 | { 32 | if (size == elements.Length) 33 | { 34 | this.resize(); 35 | } 36 | elements[size++] = e; 37 | } 38 | ``` 39 | Primeiramente, se o número de elementos for igual ao tamanho do List, será chamado o método **.resize()**. Então, o objeto será adicionado no final do array (após o incrementar o valor de *size*, o valor é passado como índice). 40 | 41 | ### Método Resize 42 | É um método chamado internamente pela classe sempre quando o tamanho atinge o mesmo valor do número de elementos, esse é o método responsável pela **alocação dinâmica** do número de objetos que o List guarda. Então, o valor do número de elementos no array nativo implementado na classe, multiplicado por dois é guardado na variável *newSize*. 43 | Após isso, é utilizado o método **Array.Resize(** *array*, *array*, *int* **)**[¹](http://www.source-code.biz/snippets/csharp/1.htm) [²](https://docs.microsoft.com/pt-br/dotnet/api/system.array.resize?view=netcore-2.2) que copia um array para outro com um novo tamanho, e é passado então para que elements seja aumentado com o tamanho definido em *newSize*. 44 | ```C# 45 | public void resize() 46 | { 47 | int newSize = elements.Length * 2; 48 | Array.Resize(ref elements, newSize); 49 | } 50 | ``` 51 | ### Método Get 52 | O método **.Get(** *int index* **)** é implementado recebendo um indice e retornando um objeto do tipo genérico. Primeiramente, é checado se o indice é valido (menor que zero ou maior que o tamanho do array) e caso seja inválido, então é retornado a exceção IndexOutOfRangeException. Caso seja válido, é retornado o elemento no array *elements* no indice passado com cast para o objeto genérico passado. 53 | 54 | ```C# 55 | public T get(int i) 56 | { 57 | if (i >= size || i < 0) 58 | { 59 | throw new System.IndexOutOfRangeException("Index: " + i + ", Size " + i ); 60 | } 61 | return (T) elements[i]; 62 | } 63 | ``` 64 | # Referências 65 | - [Trabalho com listas - Caelum](https://www.caelum.com.br/apostila-csharp-orientacao-objetos/trabalhando-com-listas/) 66 | - [How to implement an ArrayList structure in Java - Tutorial](https://www.vogella.com/tutorials/JavaDatastructureList/article.html) 67 | -------------------------------------------------------------------------------- /Data Structures/Lists/LinkedList/Implementation/LinkedList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public class LinkedList 4 | { 5 | // Propriedade que guarda o nó da primeira posição 6 | private Node head; 7 | 8 | // Método printAllNodes 9 | // Des: 10 | // Recebe: 11 | // Retorna: 12 | public void printAllNodes() 13 | { 14 | Node current = head; 15 | while (current != null) 16 | { 17 | Console.WriteLine(current.data); 18 | current = current.next; 19 | } 20 | } 21 | 22 | // Método AddFirst 23 | // Des: Adiciona o objeto passado como primeiro da lista 24 | // Recebe: Objeto (qualquer) data 25 | // Retorna: void 26 | public void AddFirst(Object data) 27 | { 28 | Node toAdd = new Node(); 29 | toAdd.data = data; 30 | toAdd.next = head; 31 | head = toAdd; 32 | } 33 | 34 | // Método AddLast 35 | // Des: Adiciona o objeto passado como último da lista 36 | // Recebe: Objeto (qualquer) data 37 | // Retorna: void 38 | public void AddLast(Object data) 39 | { 40 | // se o primeiro não possui nenhum no (lista vazia) 41 | // adiciona o objeto passado como head e o próximo nulo 42 | if (head == null) 43 | { 44 | head = new Node(); 45 | head.data = data; 46 | head.next = null; 47 | } 48 | else 49 | { 50 | // caso contrario 51 | // guarda o objeto como objeto a ser adicionado 52 | Node toAdd = new Node(); 53 | toAdd.data = data; 54 | // passa o primeiro no como no atual 55 | Node current = head; 56 | while (current.next != null) 57 | { 58 | // enquanto o proximo no nao for nulo 59 | // o no atual recebe o valor do proximo no atual 60 | current = current.next; 61 | } 62 | // quando nao houver mais dados no proximo no 63 | // o no que guarda o objeto a ser adicionado 64 | // é guardado como proximo no do atual 65 | current.next = toAdd; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Data Structures/Lists/LinkedList/Implementation/Node.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public class Node 4 | { 5 | // proximo no na rede guardado como objeto 6 | public Node next; 7 | // no atual guardado 8 | public Object data; 9 | } 10 | -------------------------------------------------------------------------------- /Data Structures/Lists/LinkedList/Implementation/Program.cs: -------------------------------------------------------------------------------- 1 | class Program 2 | { 3 | static void Main(string[] args) 4 | { 5 | Console.WriteLine("Add First:"); 6 | LinkedList myList1 = new LinkedList(); 7 | 8 | myList1.AddFirst("Hello"); 9 | myList1.AddFirst("Magical"); 10 | myList1.AddFirst("World"); 11 | myList1.printAllNodes(); 12 | 13 | Console.WriteLine(); 14 | 15 | Console.WriteLine("Add Last:"); 16 | LinkedList myList2 = new LinkedList(); 17 | 18 | myList2.AddLast("Hello"); 19 | myList2.AddLast("Magical"); 20 | myList2.AddLast("World"); 21 | myList2.printAllNodes(); 22 | 23 | Console.ReadLine(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Data Structures/Lists/LinkedList/README.md: -------------------------------------------------------------------------------- 1 | # LinkedList 2 | A LinkedList é uma estrutura de dados linear, consiste de um grupo de nós em sequência. Os nós possuem duas informações, o dado ou objeto que guardam e a referência para o próximo nó. Elas possuem natureza dinâmica como os Lists (ArrayLists), porém por ser sequencial oferece vantagem nas operações de inserção e remoção de dados/objetos guardados, perdendo performance nas operações de modificar ou receber os dados armazenados. Ela é a estrutura básica utilizada para implementar outras estruturas mais complexas como Filas[¹](https://pt.wikibooks.org/wiki/Algoritmos_e_Estruturas_de_Dados/Filas), Pilhas[²](https://pt.wikibooks.org/wiki/Algoritmos_e_Estruturas_de_Dados/Pilhas) e Árvores[³](https://pt.wikibooks.org/wiki/Algoritmos_e_Estruturas_de_Dados/Árvore). 3 | 4 |

5 | 6 |

7 | 8 | ## Tipos de LinkedList 9 | - **Single LinkedList**: Cada nó contêm a informação do próximo nó e o dado que estão guardando, fazendo com que todos os acessos sejam sequenciais sempre do primeiro até o último nó. 10 | 11 |

12 | 13 |

14 | 15 | - **Double LinkedList**: Cada nó contêm a informação do nó anterior e do próximo nó, além do dado que estão guardando. Permitindo que sejam acessados tanto do primeiro até o último nó, quanto do último até o primeiro nó. 16 | 17 |

18 | 19 |

20 | 21 | - **Circular LinkedList**: Estrutura similar ao single linkedlist em que cada nó contêm a informação do próximo nó e o dado que estão guardando, exceto pelo último nó guardar a referência do primeiro, permitindo que seu acesso possa facilmente ser reiniciado. 22 | 23 |

24 | 25 |

26 | 27 | ## Implementação de uma Single LinkedList em C# 28 | Optei por mostrar a implementação de uma *Single LinkedList* por ser a estrutura mais simples de implementar, mas a partir de sua implementação é fácil de implementar *Double LinkedLists* (adicionando a ref. do nó anterior ao nó) e *Circular LinkedLists* (adicionando a ref. do primeiro nó caso o próximo seja nulo). 29 | 30 | - [Node.cs](https://github.com/Camilotk/aprendendo_csharp/blob/master/Data%20Structures/Lists/LinkedList/Implementation/Node.cs) 31 | - [LinkedList.cs](https://github.com/Camilotk/aprendendo_csharp/blob/master/Data%20Structures/Lists/LinkedList/Implementation/LinkedList.cs) 32 | ## Node.cs 33 | Node (nó) é uma **classe autorreferencial**, ou seja, contêm uma propriedade que instancia um objeto que é da mesma classe que a própria classe. Neste caso, Node, armazena o próximo Node (nó) guardando-o na propriedade do próprio tipo *next*. O nó também possui outra propriedade chamada data que guarda o objeto genérico () ou gerar(Object) armazenado na LinkedList. 34 | 35 | ### Propriedades 36 | ```C# 37 | public Node next; 38 | public Object data; 39 | ``` 40 | ## LinkedList.cs 41 | 42 | ### Propriedades 43 | A única propriedade que a forma mais simples de LinkedList implementa (pode implementar mais propriedades conforme implementação, como *tail*...) é a propriedade privada *head* que guarda o nó que está na ponta da LinkedList (último adicionado). 44 | 45 | ```C# 46 | private Node head; 47 | ``` 48 | ### Método AddFirst 49 | O método **.AddFirst(** *Object* ou ** **)**, primeiramente instancia um novo nó. Coloca o objeto passado como a propriedade *data* do Node (nó). Então, coloca o nó antigo (mesmo se for null) como next. Após isso, coloca o nó instanciado como a propriedade *head* da LinkedList, que representa o último nó adicionado. 50 | 51 | ```C# 52 | public void AddFirst(Object data) 53 | { 54 | Node toAdd = new Node(); 55 | toAdd.data = data; 56 | toAdd.next = head; 57 | head = toAdd; 58 | } 59 | ``` 60 | ### Método AddLast 61 | O método **.AddLast(** ** *Object* ou ** **)**, primeiramente checa se o último nó não existe (null), caso seja, instancia um novo nó que recebe o objeto como *data* (dados) e null como *next* (próximo nó). Caso exista, ele instancia um novo nó que recebe o objeto passado como *data* (dados) e então percorre toda a lista até o último elemento, quando chega ao último (primeiro adicionado) ele coloca esse nó criado como *next*. 62 | 63 | ```C# 64 | public void AddLast(Object data) 65 | { 66 | if (head == null) 67 | { 68 | head = new Node(); 69 | head.data = data; 70 | head.next = null; 71 | } 72 | else 73 | { 74 | Node toAdd = new Node(); 75 | toAdd.data = data; 76 | Node current = head; 77 | while (current.next != null) 78 | { 79 | current = current.next; 80 | } 81 | current.next = toAdd; 82 | } 83 | } 84 | ``` 85 | # Referências 86 | - [What is linked list?](https://www.quora.com/What-is-linked-list-1) 87 | - [Algoritmos e Estruturas de Dados/Lista encadeada](https://pt.wikibooks.org/wiki/Algoritmos_e_Estruturas_de_Dados/Lista_encadeada) 88 | -------------------------------------------------------------------------------- /Data Structures/Lists/LinkedList/circular_linkedlist.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Camilotk/aprendendo_csharp/29e161b6b4d7ef9155cfbd5aeac95cc726bc8fd7/Data Structures/Lists/LinkedList/circular_linkedlist.webp -------------------------------------------------------------------------------- /Data Structures/Lists/LinkedList/double_linkedlist.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Camilotk/aprendendo_csharp/29e161b6b4d7ef9155cfbd5aeac95cc726bc8fd7/Data Structures/Lists/LinkedList/double_linkedlist.webp -------------------------------------------------------------------------------- /Data Structures/Lists/LinkedList/linked_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Camilotk/aprendendo_csharp/29e161b6b4d7ef9155cfbd5aeac95cc726bc8fd7/Data Structures/Lists/LinkedList/linked_list.png -------------------------------------------------------------------------------- /Data Structures/Lists/LinkedList/single_linkedlist.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Camilotk/aprendendo_csharp/29e161b6b4d7ef9155cfbd5aeac95cc726bc8fd7/Data Structures/Lists/LinkedList/single_linkedlist.webp -------------------------------------------------------------------------------- /Data Structures/Lists/README.md: -------------------------------------------------------------------------------- 1 | # Lists 2 | Uma List (às vezes chamada de sequência) é uma coleção ordenada que pode conter elementos duplicados. Como os arrays, índices de uma lista seguem a numeração baseada em zero (Zero-based numbering)[¹](https://en.wikipedia.org/wiki/Zero-based_numbering). As listas ordenadas herdam das interfaces IEnumerable, ICollection e IList. Nessa categoria estão as estruturas **List** (*ou ArrayList*) e **LinkedList**. A classe List é uma implementação de array redimensionável com acesso randômico. LinkedLists são coleções ordenadas em que cada nó (objeto que contêm a informação) também contenha a referência para o próximo nó, fazendo com que assim todos fiquem ordenados um após o outro. 3 | 4 | **Obs:** Em C#, a implementação padrão da linguagem de um ArrayList permite ser feita pelas classes **List** e **ArrayList** como pode ser visto melhor [aqui](https://stackoverflow.com/a/50736397). 5 | 6 | ## Diferenças de Performance 7 | Inserir um elemento entre os elementos existentes de um ArrayList é uma operação ineficiente — todos os elementos depois do novo devem ser removidos, o que pode ser uma operação cara em uma coleção com um grande número de elementos. Uma LinkedList permite a inserção (ou remoção) eficiente dos elementos no meio de uma coleção, mas é muito menos eficiente que um ArrayList para pular para um elemento específico na coleção. 8 | 9 | | | List (ArrayList)| LinkedList | 10 | |----------|-----------------|-----------------| 11 | | get() | O(1) | O(n) | 12 | | add() | O(1) | O(1) amortizado | 13 | | remove() | O(n) | O(n) | 14 | 15 | ## Indice de Listas 16 | - [List](https://github.com/Camilotk/aprendendo_csharp/tree/master/Data%20Structures/Lists/ArrayList) 17 | - [LinkedList](https://github.com/Camilotk/aprendendo_csharp/tree/master/Data%20Structures/Lists/LinkedList) 18 | 19 | ### Referências 20 | - [When should I use a List vs a LinkedList?](https://stackoverflow.com/a/169983) 21 | - [When to use LinkedList over ArrayList in Java?](https://stackoverflow.com/questions/322715/when-to-use-linkedlist-over-arraylist-in-java) 22 | - [ArrayList vs. LinkedList vs. Vector](https://www.programcreek.com/2013/03/arraylist-vs-linkedlist-vs-vector/) 23 | -------------------------------------------------------------------------------- /Data Structures/README.md: -------------------------------------------------------------------------------- 1 | # Estrutura de Dados 2 | Estrutura de Dados, são coleções - _sets_ (conjuntos) - de dados. Cada estrutura define formas de organizar essas coleções para que atendam determinada necessidade do Programa, seja performace, segurança... Em linguagens Orientadas a Objetos como Java e C#, as coleções são construídas através de Objetos, enquanto em liguagens procedurais como Pascal e C são construídas através de Records/Structs e Ponteiros, ou seja em C#, as Estruturas de Dados também são Objetos, assim como os dados que armazenam. 3 | 4 | Existem interfaces que definem as ações genéricas que cada grupo de coleções deve implementar. A **tabela abaixo** as interfaces usadas. 5 | 6 | Também é possivel usar essas interfaces para fazer as próprias implementações. As classes das coleções são partes do **namespace** System.Collections[¹](https://docs.microsoft.com/pt-br/dotnet/api/system.collections?view=netcore-2.2) que contêm todas as interfaces e classes que são necessárias para implementar coleções, divididas em Coleções (Classes e Interfaces usadas *somente* pelas implementações padrões da linguagem) e as Coleções Genéricas (Permitem especificar o tipo exato que será armazenado em uma coleção e fornecem os benefícios da verificação de tipo em tempo de compilação — o compilador emite mensagens de erro se você usar tipos inadequados nas coleções. Depois de especificar o tipo armazenado em uma coleção genérica, qualquer referência que você recupera da coleção terá esse tipo). 7 | 8 | | Interface | Motivo | Doc. | Doc. Genérica | 9 | |-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------| 10 | | IEnumerable | Enumera a coleção para dar suporte (permitir) o comando foreach. | [IEnumerable](https://docs.microsoft.com/pt-br/dotnet/api/system.collections.ienumerable?view=netcore-2.2) | [IEnumerable<T>](https://docs.microsoft.com/pt-br/dotnet/api/system.collections.generic.ienumerable-1?view=netcore-2.2) | 11 | | ICollection | Implementa todas as ações que todas as coleções devem possuir, como o método CopyTo() assim como as propriedades Count, ISReadOnly, ISSynchronized e SyncRoot | [ICollection](https://docs.microsoft.com/pt-br/dotnet/api/system.collections.icollection?view=netcore-2.2) | [ICollection<T>](https://docs.microsoft.com/pt-br/dotnet/api/system.collections.generic.icollection-1?view=netcore-2.2) | 12 | | IComparer | Compara dois objetos em uma coleção para que a coleção possa ser ordenada. | [IComparer](https://docs.microsoft.com/pt-br/dotnet/api/system.collections.icomparer?view=netcore-2.2) | [IComparer<T>](https://docs.microsoft.com/pt-br/dotnet/api/system.collections.generic.icomparer-1?view=netcore-2.2) | 13 | | IList | Implementa todas as ações de coleções que podem ser acessadas por índice. | [IList](https://docs.microsoft.com/pt-br/dotnet/api/system.collections.ilist?view=netcore-2.2) | [IList<T>](https://docs.microsoft.com/pt-br/dotnet/api/system.collections.generic.ilist-1?view=netcore-2.2) | 14 | | IDictionary | Implementa todas as ações de coleções que são baseadas em chave-valor, como HashTable e SortedList. | [IDictionary](https://docs.microsoft.com/pt-br/dotnet/api/system.collections.idictionary?view=netcore-2.2) | [IDictionary](https://docs.microsoft.com/pt-br/dotnet/api/system.collections.generic.idictionary-2?view=netcore-2.2) | 15 | | IDictionaryEnumerator | Permite enumerar a coleção para dar suporte (permitir) o comando foreach quando ela implementa um IDictionary | [IDictionaryEnumerator](https://docs.microsoft.com/pt-br/dotnet/api/system.collections.idictionaryenumerator?view=netcore-2.2) | | 16 | 17 | **Obs:** Evite reinventar a roda — em vez de construir suas próprias estruturas de dados, utilize as interfaces e coleções da estrutura das coleções do C#, que foram cuidadosamente testadas e ajustadas para atender aos requisitos da maioria dos aplicativos. Este repositório e estudo é para entender como as coisas funcionam e não com o objetivo de _reescrever_ algo que foi implementado pela linguagem. 18 | 19 | ### Relação das Interfaces e Collections 20 | ![Relação das Interfaces](https://github.com/Camilotk/aprendendo_csharp/blob/master/Data%20Structures/interfaces_csharp.png) 21 | 22 | ## Indice de Estruturas de Dados 23 | * básicas: 24 | - [Lists](https://github.com/Camilotk/aprendendo_csharp/tree/master/Data%20Structures/Lists) 25 | - [Sets](https://github.com/Camilotk/aprendendo_csharp/tree/master/Data%20Structures/Sets) 26 | - Dictionaries 27 | * derivadas: 28 | - Heap 29 | - Queue 30 | - Tree 31 | -------------------------------------------------------------------------------- /Data Structures/Sets/HashSet/Implementation/MyHashSet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SetsTest.HashSet 5 | { 6 | // O HashSet é um conjunto de objetos únicos não ordenados organizados em 7 | // coleção, internamente ele implementa uma Hash Table (Dictionary em C#) 8 | // que armazena o Objeto passado e garante que não haja repetição de items 9 | // 10 | // OBS: Caso queira entender a implementação de Dictionary veja a 11 | // seção de Dictionaries em Estrutura de Dados 12 | public class MyHashSet 13 | { 14 | // A Classe HashSet implementa internamente um Dictionary (HashTable) 15 | // que irá guardar uma chave do tipo genérico do conjunto e um objeto 16 | // que diz se ele já está presente na coleção. 17 | Dictionary map; 18 | // Define o Objeto que indica se o Objeto está presente ou não 19 | private static readonly Object PRESENT = new Object(); 20 | // Guarda um valor inteiro positivo que representa o número de objetos 21 | // no map 22 | private uint numberOfElements; 23 | 24 | public MyHashSet() 25 | { 26 | numberOfElements = 0; 27 | map = new Dictionary(); 28 | } 29 | 30 | // Retorna o número de elementos dentro do HashSet 31 | public uint Count => numberOfElements; 32 | 33 | // Adiciona um novo Objeto ao HashSet 34 | public bool Add(T item) 35 | { 36 | try 37 | { 38 | // Tenta adicionar um novo objeto ao Map 39 | // Caso ele já exista irá lançar uma Exceção 40 | map.Add(item, PRESENT); 41 | numberOfElements++; 42 | return true; 43 | } 44 | catch(ArgumentException e) 45 | { 46 | // Caso a exceção seja que o Objeto já existe 47 | // irá imprimir o erro e retornar falso 48 | // 49 | // obs: comente essa linha para suprimir a mensagem 50 | Console.WriteLine(e.Message); 51 | return false; 52 | } 53 | catch(Exception) 54 | { 55 | // Qualquer outra exceção irá apenas retornar falso 56 | return false; 57 | } 58 | } 59 | 60 | public void Clear() 61 | { 62 | // Limpa o HashSet 63 | map.Clear(); 64 | } 65 | 66 | public bool Contains(T item) 67 | { 68 | // Retorna se o elemento do tipo genérico passsado 69 | // está presente no HashSet 70 | return map.ContainsKey(item); 71 | } 72 | 73 | public IEnumerator GetEnumerator() 74 | { 75 | return map.Keys.GetEnumerator(); 76 | } 77 | 78 | public bool Remove(T item) 79 | { 80 | // Retorna se a chave do Map foi encontrada e corretamente removida 81 | return map.Remove(item); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Data Structures/Sets/HashSet/README.md: -------------------------------------------------------------------------------- 1 | # HashSet 2 | Os HashSets (Conjunto de Dispersão) é um tipo de estrutura que tenta otimizar o trabalho de uma Lista para que contenha apenas valores únicos. Além disso, a garantia de unicidade também facilida o trabalho de busca por determinado item, uma vez em que o HashSet categoriza os items armazenados de forma que consiga garantir de forma eficiente que não há nenhum elemento duplicado. Os HashSets depedem diretamente da função **.GetHashCode()** que pertence à Classe Object do C#, essa função retorna um código único**¹** para cada objeto o que garante que cada objeto contido no Conjunto é único. 3 | 4 | Assim como LinkedLists implementam um Array primitivo que armazena os objetos passados, os HashSets implementam uma estrutura de Dicionário que recebe dois valores, o valor passado em si e o objeto que representa se o objeto passado já está inserido ou não. 5 | 6 |
7 |
8 | 9 |
10 |
11 | Exemplo de HashTable - Dicionário - que armazena os elementos. 12 |
13 |
14 |
15 | 16 | ## Implementação básica em C# 17 | - [MyHashSet.cs](https://github.com/Camilotk/aprendendo_csharp/blob/master/Data%20Structures/Sets/HashSet/Implementation/MyHashSet.cs) 18 | 19 | ## Imports 20 | **Linhas 1 e 2** 21 | 22 | Para que possamos utilizar a estrutura de dicionário padrão do C# para implementar nosso HashSet é necessário primeiro importar as coleções genéricas. 23 | 24 | ```C# 25 | using System; 26 | using System.Collections.Generic; 27 | ``` 28 | 29 | ### Propriedades 30 | **Linhas 17 a 22** 31 | 32 | A propriedade **map** é a HashTable (Tabela de Disperção) que guarda os objetos passados, a maior parte das implementações já vem por default dos métodos que a classe Dictionary das collections de C# possui. 33 | 34 | A propriedade PRESENT é uma propriedade imutável do tipo objeto sem implementação derivada que representa o objeto adicionado, ele serve para checar se um dos objetos inseridos já está no conjunto ou se o objeto buscado está presente no conjunto. 35 | 36 | A propriedade do tipo unsigned integer (inteiro positivo ou I+) é o número de elementos já adicionados ao conjunto. 37 | 38 | ```C# 39 | Dictionary map; 40 | private static readonly Object PRESENT = new Object(); 41 | private uint numberOfElements; 42 | ``` 43 | ### Método Construtor 44 | **Linhas 24 a 28** 45 | 46 | O método construtor público e sem parâmetros simplesmente inicializa o número de elementos em 0 e instancia o novo dicionário que irá guardar os elementos do HashSet. 47 | 48 | ```C# 49 | public MyHashSet() 50 | { 51 | numberOfElements = 0; 52 | map = new Dictionary(); 53 | } 54 | ``` 55 | 56 | ### Método .Add() 57 | **Linhas de 34 a 58** 58 | 59 | O método **.Add(** *Object* **)** recebe um item do tipo genérico do HashSet e utiliza a estrutura de try-catch para tentar adicionar esse elemento no dicionário **map**, caso seu Hash já esteja registrado em map, irá retornar uma exeção **ArgumentException** que será tratada e irá imprimir no console que esse objeto já está adicionado ao map. Qualquer outra exceção retorna falso. 60 | 61 | ```C# 62 | public bool Add(T item) 63 | { 64 | try 65 | { 66 | map.Add(item, PRESENT); 67 | numberOfElements++; 68 | return true; 69 | } 70 | catch(ArgumentException e) 71 | { 72 | Console.WriteLine(e.Message); 73 | return false; 74 | } 75 | catch(Exception) 76 | { 77 | return false; 78 | } 79 | } 80 | ``` 81 | 82 | ### Método .Clear() 83 | **Linhas 60 a 64** 84 | 85 | Simplesmente limpa o map, utiliza-se da própria implantação do mesmo. 86 | ```C# 87 | public void Clear() 88 | { 89 | map.Clear(); 90 | } 91 | ``` 92 | 93 | ### Método .Contains() 94 | **Linhas 66 a 71** 95 | 96 | Retorna um valor booleano se o elemento do tipo genérico passsado está presente no HashSet, utiliza-se da própria implantação do mesmo. 97 | ```C# 98 | public bool Contains(T item) 99 | { 100 | return map.ContainsKey(item); 101 | } 102 | ``` 103 | 104 | ### Método .Remove() 105 | **Linhas 78 a 82** 106 | 107 | No caso de C# - diferentemente de Java - a função .Remove() de map retorna um valor booleano que diz se o objeto foi corretamente removido, o que nos permite dispensar o uso de try-catch simplesmente retornando o retorno da função de map. 108 | 109 | ```C# 110 | public bool Remove(T item) 111 | { 112 | return map.Remove(item); 113 | } 114 | ``` 115 | 116 | ## Exemplo de Uso 117 | Podemos passar todos os itens de uma lista para um conjunto com a finalidade de garantir que não haja itens repetidos. 118 | 119 | ```C# 120 | using System; 121 | using System.Collections.Generic; 122 | using SetsTest.HashSet; 123 | 124 | namespace SetsTest 125 | { 126 | class Program 127 | { 128 | // Oranges, peach, pears, plums, syringes 129 | static void Main(string[] args) 130 | { 131 | List fruits = new List(){ 132 | "apples", 133 | "oranges", 134 | "peaches", 135 | "pears", 136 | "oranges", 137 | "pears", 138 | "blueberrys", 139 | "apples" 140 | 141 | }; 142 | 143 | MyHashSet fruits_group = new MyHashSet(); 144 | Console.WriteLine("---------"); 145 | foreach (var fruit in fruits) 146 | { 147 | fruits_group.Add(fruit); 148 | } 149 | Console.WriteLine("---------"); 150 | foreach (var fruit in fruits_group) 151 | { 152 | Console.WriteLine(fruit); 153 | } 154 | Console.WriteLine("---------"); 155 | Console.WriteLine("Elementos no Conjunto: {0}", fruits_group.Count); 156 | } 157 | } 158 | } 159 | ``` 160 | **Output:** 161 | ``` 162 | --------- 163 | An item with the same key has already been added. Key: oranges 164 | An item with the same key has already been added. Key: pears 165 | An item with the same key has already been added. Key: apples 166 | --------- 167 | apples 168 | oranges 169 | peaches 170 | pears 171 | blueberrys 172 | --------- 173 | Elementos no Conjunto: 5 174 | ``` 175 | # Referências 176 | - [How HashSet is internally implemented in Java?](https://codepumpkin.com/hashset-internal-implementation/) 177 | - [VERY simple C# Set implementation](https://codereview.stackexchange.com/questions/126263/very-simple-c-set-implementation/126266) 178 | - [Lidando com conjuntos](https://www.caelum.com.br/apostila-csharp-orientacao-objetos/lidando-com-conjuntos/) 179 | - [Set - Wikipedia](https://en.wikipedia.org/wiki/Set_(abstract_data_type)) 180 | - [HashTable - Wikipedia](https://en.wikipedia.org/wiki/Hash_table) 181 | -------------------------------------------------------------------------------- /Data Structures/Sets/README.md: -------------------------------------------------------------------------------- 1 | # Sets 2 | Os *Sets* (Conjuntos) são coleções de objetos e valores únicos. Existem diversas implementações de Set para diferentes finalidades, entre elas o **HashSet** (*não ordenados*) e o **SortedSet** (*ordenados*). Os elementos em armazenados em um Set são diferenciados pelo valor de Hash [1](https://pt.wikipedia.org/wiki/Fun%C3%A7%C3%A3o_hash) devolvido pelo método **.GetHashCode()** da Classe Object da qual todos os objetos herdam, isso pode ser consultado mais profundamente na [documentação](https://docs.microsoft.com/pt-br/dotnet/api/system.object.gethashcode?view=netcore-3.0). A Coleção de Set, é implementada pela interface ISet que define todos os comportamentos esperados de uma Set Collection, assim como as interfaces ICollection e IEnumerable. Diferentemente de Listas, em Conjuntos, não há como obter elementos por índice de um conjunto, sendo necessário iterar os itens a partir de um **foreach()** ou então obter o item esperado diretamente passando-o no método **.Get(** *Object* **)** do conjunto. Isso acontece porque tratando-se de Conjuntos **não existe ordem**, os itens são contatemente reorganizados à medida em que são inseridos seja por ordem de Hash no caso do HashSet ou por ordem de algum atributo como no caso do SortedSet. 3 | 4 | ## Diferenças de Uso 5 | 6 | Os HashSets e SortedLists possuem diferentes usos dependendo do tipo de problema que se está resolvendo, sua principal diferença por baixo dos panos é que os HashSets utilizam-se da implementação de um algoritmo de Hash Table (Tabela de Dispersão) [2](https://pt.wikipedia.org/wiki/Tabela_de_dispers%C3%A3o) com a finalidade de armazenar os dados em conjuntos sem que haja a repetição, uma característica dessse algoritmo é uma maior eficiência em processamento e velocidade, porém os itens ficam organizados de forma não ordenada e uma nova inserção pode resultar em uma reorganização (realocação) dos indices da coleção como um todo, enquanto o SortedSet utiliza-se de balanced binary-tree ou red-black tree (Árvores Rubro-negras) [3](https://pt.wikipedia.org/wiki/%C3%81rvore_rubro-negra) para organizar as coleções, o que resulta em algoritmos que exigem maior computação, porém capazes de armazenar os dados de forma ordenada o que permite buscas eficientes e operações como fatiamento de listas [4](https://docs.microsoft.com/pt-br/dotnet/api/system.collections.generic.sortedset-1.getviewbetween?view=netcore-3.0#System_Collections_Generic_SortedSet_1_GetViewBetween__0__0_) de forma precisa e segura. 7 | 8 | ## Eficiência 9 | |Operação| HashSet (*Média*) | HashSet (*Pior Caso*) | SortedSet (*Média*) | SortedSet(*Pior Caso*)| 10 | |--------|-------------------|-----------------------|---------------------|-----------------------| 11 | | Search | O(1) | O(n) | O(*log n*) | O(*log n*) | 12 | | Insert | O(1) | O(n) | O(*log n*) | O(*log n*) | 13 | | Delete | O(1) | O(n) | O(*log n*) | O(*log n*) | 14 | 15 | ## Índice de Sets 16 | - [HashSet](https://github.com/Camilotk/aprendendo_csharp/tree/master/Data%20Structures/Sets/HashSet) 17 | - [SortedSet](https://github.com/Camilotk/aprendendo_csharp/tree/master/Data%20Structures/Sets/SortedSet) 18 | 19 | ### Referências 20 | - [SortedSet vs HashSet](https://stackoverflow.com/questions/4622736/sortedsett-vs-hashsett) 21 | - [Trabalhando com a Interface Set no Java](http://www.linhadecodigo.com.br/artigo/3669/trabalhando-com-a-interface-set-no-java.aspx) 22 | - [Set Operations](https://docs.microsoft.com/pt-br/dotnet/csharp/programming-guide/concepts/linq/set-operations) 23 | -------------------------------------------------------------------------------- /Data Structures/Sets/SortedSet/Implementation/MySortedSet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SetsTest.SortedSet 4 | { 5 | public class MySortedSet where T : IComparable 6 | { 7 | private RedBlackTree _elements { get; set; } 8 | 9 | public MySortedSet () => _elements = new RedBlackTree(); 10 | 11 | public int Count() 12 | { 13 | return Convert.ToInt32(_elements.numberOfElements); 14 | } 15 | 16 | public bool Add(T item) 17 | { 18 | try 19 | { 20 | _elements.Add(item); 21 | return true; 22 | } 23 | catch(Exception e) 24 | { 25 | Console.WriteLine(e.Message); 26 | return false; 27 | } 28 | 29 | } 30 | 31 | public bool Remove(T item) 32 | { 33 | try 34 | { 35 | _elements.Remove(item); 36 | return true; 37 | 38 | } 39 | catch(Exception e) 40 | { 41 | Console.WriteLine(e.Message); 42 | return false; 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Data Structures/Sets/SortedSet/Implementation/RedBlackTree.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SetsTest.SortedSet 4 | { 5 | public class RedBlackTree where T : IComparable 6 | { 7 | private class Node 8 | { 9 | // Propriedades: 10 | // item do tipo genérico 11 | private T item; 12 | // autoreferencia ao nó da esquerda 13 | private Node left; 14 | // autoreferencia ao nó da direita 15 | private Node right; 16 | // autoreferencia ao nó de cima 17 | private Node parent; 18 | // valor booleano se o nó é vermelho ou não 19 | private bool red = true; 20 | 21 | public Node Left { 22 | get 23 | { 24 | return left; 25 | } 26 | set 27 | { 28 | left = value; 29 | } 30 | } 31 | 32 | public Node Right { 33 | get 34 | { 35 | return right; 36 | } 37 | set 38 | { 39 | right = value; 40 | } 41 | } 42 | 43 | public Node Parent { 44 | get 45 | { 46 | return parent; 47 | } 48 | set 49 | { 50 | parent = value; 51 | } 52 | } 53 | 54 | public bool Red 55 | { 56 | get 57 | { 58 | return red; 59 | } 60 | set 61 | { 62 | red = value; 63 | } 64 | } 65 | 66 | public T Item 67 | { 68 | get 69 | { 70 | return item; 71 | } 72 | set 73 | { 74 | item = value; 75 | } 76 | } 77 | 78 | // Construtor: 79 | // Recebe: 80 | // - T item: item do tipo genérico 81 | // - Node parent: nó superior 82 | //Descrição: 83 | // Guarda o item e adiciona qual o nó que gerou este como acima 84 | public Node(T item, Node parent) 85 | { 86 | this.item = item; 87 | this.parent = parent; 88 | this.left = null; 89 | this.right = null; 90 | } 91 | } 92 | // --------------------- 93 | 94 | //Propriedades: 95 | // Primeiro nó 96 | private Node root; 97 | // Número de Elementos 98 | public uint numberOfElements { get; set; } 99 | // Nó inserido 100 | private Node insertedNode; 101 | // Nó que sendo deletado 102 | private Node nodeBeingDeleted; 103 | // Tem parente a esquerda? 104 | private bool siblingToRight; 105 | // 106 | private bool parentToRight; 107 | // Nó para deletar vermelho 108 | private bool nodeToDeleteRed; 109 | 110 | // Método Adicionar 111 | // Recebe: 112 | // - T item: item do tipo genérico da classe 113 | // Descrição: 114 | // - Adiciona um novo item à árvore 115 | public void Add(T item) 116 | { 117 | root = InsertNode(root, item, null); 118 | numberOfElements++; 119 | if(numberOfElements > 2) 120 | { 121 | Node parent; 122 | Node grandParent; 123 | Node greatGrandParent; 124 | } 125 | } 126 | 127 | // Método Rotacionar (Direita e Esquerda) 128 | // Recebe: 129 | // - Node node: Nó por referencia - muda seu valor original. 130 | // Descrição: 131 | // - Reordena os nós para que o nó acima, direita e esquerda rotacionem em sentido horário 132 | // ou antihorário 133 | private void LeftRotate(ref Node node) 134 | { 135 | Node nodeParent = node.Parent; 136 | Node right = node.Right; 137 | Node temp = right.Left; 138 | right.Left = node; 139 | node.Parent = right; 140 | node.Right = temp; 141 | 142 | if (temp != null) 143 | { 144 | temp.Parent = node; 145 | } 146 | 147 | if (right != null) 148 | { 149 | right.Parent = nodeParent; 150 | } 151 | 152 | node = right; 153 | } 154 | 155 | 156 | private void RightRotate(ref Node node) 157 | { 158 | Node nodeParent = node.Parent; 159 | Node left = node.Left; 160 | Node temp = left.Right; 161 | left.Right = node; 162 | node.Parent = left; 163 | node.Left = temp; 164 | 165 | if (temp != null) 166 | { 167 | temp.Parent = node; 168 | } 169 | 170 | if (left != null) 171 | { 172 | left.Parent = nodeParent; 173 | } 174 | 175 | node = left; 176 | } 177 | 178 | // Inserir Nó 179 | // Recebe: 180 | // - Node node: Objeto nó, com as informações 181 | // - T item: Objeto genérico a ser guardado no nó 182 | // - Node parent: Nó que gerou esse nó 183 | // Descrição: 184 | // Insere um novo nó, comparando com os existentes e/ou criando novo 185 | // Retorno: 186 | // - Node newNode: Novo nó a ser inserido 187 | // - Node node: Nó a do lado a ser inserido 188 | // - InvalidOperationException: Exceção caso o nó já exista 189 | private Node InsertNode(Node node, T item, Node parent) 190 | { 191 | // Se o nó passado for nulo 192 | if (node == null) 193 | { 194 | // Instancie um novo nó 195 | Node newNode = new Node(item, parent); 196 | // Se o número de elementos for maior que 0: 197 | // O nó é vermelho 198 | // Em outros casos: 199 | // O nó é preto 200 | if (numberOfElements > 0) 201 | { 202 | newNode.Red = true; 203 | } 204 | else 205 | { 206 | newNode.Red = false; 207 | } 208 | // O Nó inserido recebe o novo Nó 209 | insertedNode = newNode; 210 | // E retorna o novo nó 211 | return newNode; 212 | } 213 | // Senão se o item a ser gravado preceder o que está gravado no nó passado 214 | else if(item.CompareTo(node.Item) < 0) 215 | { 216 | // O nó da esquerda do nó passado recebe o conteúdo passado e recebe o nó 217 | // passado como superior 218 | node.Left = InsertNode(node.Left, item, node); 219 | // Retorna o nó 220 | return node; 221 | } 222 | // Senão se o item gravado proceder o que está sendo gravado no nó passado 223 | else if(item.CompareTo(node.Item) > 0) 224 | { 225 | // O nó da direita do nó passado recebe o conteúdo passado e recebe o nó 226 | // passado como superior 227 | node.Right = InsertNode(node.Right, item, node); 228 | // Retorna o nó 229 | return node; 230 | } 231 | // Caso ele já exista 232 | else 233 | { 234 | throw new InvalidOperationException("Cannot add duplicate object"); 235 | } 236 | } 237 | 238 | // Receber os nós acima 239 | // Recebe: 240 | // - Node ourNode: Nó que passara seus nós acima 241 | // Descrição: 242 | // Pega os pais/nós acima e os guarda como pais do nó passado na estrutura de nó 243 | private void GetNodesAbove(Node ourNode, out Node parent, 244 | out Node grandParent, out Node greatGrandParent) 245 | { 246 | // Coloca os nós acima como nulos 247 | parent = null; 248 | grandParent = null; 249 | greatGrandParent = null; 250 | 251 | // Se o nó passado existir, coloque os nós acima como os que ele possui 252 | if(ourNode != null) 253 | { 254 | parent = ourNode.Parent; 255 | } 256 | 257 | // Se o nó pai - parent - existir, coloque seu pai como avó - greatParent - deste 258 | if (parent != null) 259 | { 260 | grandParent = parent.Parent; 261 | } 262 | 263 | // Se o nó avô - greatParent - exisitr, coloque seu pai como bisavô -greatGrandParent- deste 264 | if (grandParent != null) 265 | { 266 | greatGrandParent = grandParent.Parent; 267 | } 268 | 269 | } 270 | 271 | // Receber o Pai, Avô e Sobrinho 272 | // Recebe: 273 | // - Node ourNode: Nó que passará os parentes 274 | // - Node parent: Nó pai 275 | // - (out) Node grandParent: Nó avô 276 | // - (out) Node sibling: Nó sobrinho 277 | // Descrição: 278 | // Reordena a familia de nós de acordo com a estrutura correta do algoritmo 279 | private void GetParentGrandParentSibling(Node ourNode, Node parent, 280 | out Node sibling, out Node grandParent) 281 | { 282 | // Esvazia os valores out 283 | sibling = null; 284 | grandParent = null; 285 | 286 | // Se o Pai existir 287 | if (parent != null) 288 | { 289 | // E o nó for igual ao da direita do nó pai 290 | if (parent.Right == ourNode) 291 | { 292 | // Ele é colocado como sobrinho 293 | siblingToRight = false; 294 | sibling = parent.Left; 295 | } 296 | // E o nó é igual é igual ao da esquerda do nó pai 297 | if (parent.Left == ourNode) 298 | { 299 | // Ele é colocado como sobrinho 300 | siblingToRight = true; 301 | sibling = parent.Right; 302 | } 303 | } 304 | 305 | // Se o Nó pai existir 306 | if (parent != null) 307 | { 308 | // Seu nó pai é colocado como avô 309 | grandParent = parent.Parent; 310 | } 311 | 312 | // Se o nó avô existir 313 | if (grandParent != null) 314 | { 315 | // E existir um nó a direita do avô 316 | if (grandParent.Right == parent) 317 | { 318 | // Existe um nó a direita 319 | parentToRight = true; 320 | } 321 | // E existir um nó a esquerda do avô 322 | if (grandParent.Left == parent) 323 | { 324 | // Existe um nó a esquerda 325 | parentToRight = false; 326 | } 327 | } 328 | } 329 | 330 | // Balança após a inserção 331 | // Recebe: 332 | // - Node child: Nó filho 333 | // - Node parent: Nó pai 334 | // - Node grandParent: Nó avô 335 | // - Node greatGrandParent: Nó bisavô 336 | // Descrição: 337 | // - Faz com que a arvore consiga se reajustar após um novo valor ser inserido 338 | private void FixAfterInsertion(Node child, Node parent, Node grandParent, 339 | Node greatGrandParent) 340 | { 341 | if (grandParent != null) 342 | { 343 | // Cria o Nó tio, que caso o nó da esquerda do nó passado como avô seja igual ao nó 344 | // passado como pai, recebe o nó à direita do Nó avô, em outros casos, recebe o Nó a 345 | // esquerda do nó avô 346 | Node uncle = (grandParent.Right == parent) ? grandParent.Left : grandParent.Right; 347 | 348 | // Se o Nó tio não for nulo E o Nó pai e tio forem vermelhos 349 | if (uncle != null && parent.Red && uncle.Red) 350 | { 351 | // O nó tio é passado para preto 352 | uncle.Red = false; 353 | // O nó pai é passado para preto 354 | parent.Red = false; 355 | // O nó avô é passado para vermelho 356 | grandParent.Red = true; 357 | 358 | // Declaramos duas variaveis que receberão os valores mais afastados 359 | Node higher = null; 360 | Node stillHigher = null; 361 | 362 | // Se o nô bisavô existir, ele é passado como maior nó 363 | if (greatGrandParent != null) 364 | { 365 | higher = greatGrandParent.Parent; 366 | } 367 | // Se existir algum valor colocado como maior nó, seu pai é guardado como ainda maior 368 | if (higher != null) 369 | { 370 | stillHigher = higher.Parent; 371 | } 372 | // Então a função é chamada recursivamente passando os valores passados como 373 | // nós acima, para que repita o mesmo processo com os nós acima 374 | FixAfterInsertion(grandParent, greatGrandParent, higher, stillHigher); 375 | } 376 | // Se o Nó tio não existir OU o pai for vermelho e o tio preto 377 | // Caso Direita-Direita 378 | else if (uncle == null || parent.Red && !uncle.Red) 379 | { 380 | if (grandParent.Right == parent && parent.Right == child) 381 | { 382 | parent.Red = false; 383 | grandParent.Red = true; 384 | 385 | if (greatGrandParent != null) 386 | { 387 | if (greatGrandParent.Right == grandParent) 388 | { 389 | LeftRotate(ref grandParent); 390 | greatGrandParent.Right = grandParent; 391 | } 392 | else 393 | { 394 | LeftRotate(ref grandParent); 395 | greatGrandParent.Left = grandParent; 396 | } 397 | } 398 | else 399 | { 400 | LeftRotate(ref root); 401 | } 402 | } 403 | } 404 | // Se o Nó avô for igual ao nó pai e o nó a direita de pai for igual ao novo 405 | // Caso Esquerda-Esquerda 406 | else if (grandParent.Left == parent && parent.Left == child) 407 | { 408 | parent.Red = false; 409 | grandParent.Red = true; 410 | 411 | if (greatGrandParent != null) 412 | { 413 | if (greatGrandParent.Right == grandParent) 414 | { 415 | RightRotate(ref grandParent); 416 | greatGrandParent.Right = grandParent; 417 | } 418 | else 419 | { 420 | RightRotate(ref grandParent); 421 | greatGrandParent.Left = grandParent; 422 | } 423 | } 424 | else 425 | { 426 | RightRotate(ref root); 427 | } 428 | } 429 | // Se o nó a esquerda de avô for igual ao passado como pai E o nó a direita do pai 430 | // igual ao novo 431 | // Caso Direita-Esquerda 432 | else if(grandParent.Right == parent && parent.Left == child) 433 | { 434 | child.Red = false; 435 | grandParent.Red = true; 436 | RightRotate(ref parent); 437 | grandParent.Right = parent; 438 | 439 | if (greatGrandParent != null) 440 | { 441 | if (greatGrandParent.Right == grandParent) 442 | { 443 | LeftRotate(ref grandParent); 444 | greatGrandParent.Left = grandParent; 445 | } 446 | else 447 | { 448 | LeftRotate(ref grandParent); 449 | greatGrandParent.Left = grandParent; 450 | } 451 | } 452 | else 453 | { 454 | LeftRotate(ref root); 455 | } 456 | } 457 | // Se o nó a direita do avô for igual ao passado como pai e o nó a direita do pai é igual ao passado 458 | // como novo 459 | // Caso Esquerda-Direita 460 | else if (grandParent.Left == parent && parent.Right == child) 461 | { 462 | child.Red = false; 463 | grandParent.Red = true; 464 | LeftRotate(ref parent); 465 | grandParent.Left = parent; 466 | 467 | if (greatGrandParent != null) 468 | { 469 | if (greatGrandParent.Right == grandParent) 470 | { 471 | RightRotate(ref grandParent); 472 | greatGrandParent.Right = grandParent; 473 | } 474 | else 475 | { 476 | RightRotate(ref grandParent); 477 | greatGrandParent.Left = grandParent; 478 | } 479 | } 480 | else 481 | { 482 | RightRotate(ref root); 483 | } 484 | } 485 | 486 | if (root.Red) 487 | { 488 | root.Red = false; 489 | } 490 | 491 | } 492 | 493 | } // Fim Fix After Insert 494 | 495 | private Node DeleteLeftMost(Node node, Node parent) 496 | { 497 | if (node.Left == null) 498 | { 499 | nodeBeingDeleted = node; 500 | if (node.Right != null) 501 | { 502 | node.Parent = parent; 503 | } 504 | return node.Right; 505 | } 506 | else 507 | { 508 | node.Left = DeleteLeftMost(node.Left, node); 509 | return node; 510 | } 511 | } 512 | 513 | private T LeftMost(Node node) 514 | { 515 | if (node.Left == null) 516 | { 517 | return node.Item; 518 | } 519 | else 520 | { 521 | return LeftMost(node.Left); 522 | } 523 | } 524 | 525 | // Deletar Nó 526 | // Recebe: 527 | // - Node node: Nó da busca 528 | // - T item: Item a ser deletado 529 | // - Node parent: Nó pai 530 | // Descrição: 531 | // Faz a busca e remoção dos itens 532 | // Retorna: 533 | // - Node node: Nó pai sem filho 534 | private Node DeleteNode(Node node, T item, Node parent) 535 | { 536 | if (node == null) 537 | { 538 | throw new InvalidOperationException("O item não existe na árvore"); 539 | } 540 | 541 | if (item.CompareTo(node.Item) < 0 ) 542 | { 543 | node.Left = DeleteNode(node.Left, item, node); 544 | } 545 | else if (item.CompareTo(node.Item) < 0) 546 | { 547 | node.Right = DeleteNode(node.Right, item, node); 548 | } 549 | else if (item.CompareTo(node.Item) == 0) 550 | { 551 | // Item encontrado 552 | nodeToDeleteRed = node.Red; 553 | nodeBeingDeleted = node; 554 | if (node.Left == null) 555 | { 556 | // Sem nós filhos, ou apenas um filho a direita 557 | node = node.Right; 558 | 559 | if (node != null) 560 | { 561 | node.Parent = parent; 562 | } 563 | } 564 | else if (node.Right == null) 565 | { 566 | // Apenas um filho a esquerda 567 | node = node.Left; 568 | node.Parent = parent; 569 | } 570 | else 571 | { 572 | T replaceWithValue = LeftMost(node.Right); 573 | node.Right = DeleteLeftMost(node.Right, node); 574 | node.Item = replaceWithValue; 575 | } 576 | } 577 | return node; 578 | } 579 | 580 | // Remover 581 | // Recebe: 582 | // - T item: Um item do tipo genérico presente na coleção 583 | // Descrição: 584 | // Exclui item chamando as funções privadas de exclusão e balanceamento. 585 | public void Remove(T item) 586 | { 587 | if (numberOfElements == 0) 588 | { 589 | root = null; 590 | } 591 | 592 | // Se o número de elementos é maior que 1 593 | if (numberOfElements > 1) 594 | { 595 | // Passa a raiz e o elemento a ser deletado 596 | root = DeleteNode(root, item, null); 597 | // Diminui o número de elementos 598 | numberOfElements--; 599 | 600 | Node ourNode = null; 601 | 602 | if (nodeBeingDeleted.Right != null) 603 | { 604 | ourNode = nodeBeingDeleted.Right; 605 | } 606 | 607 | Node parent; 608 | Node sibling; 609 | Node grandParent; 610 | 611 | if (ourNode == null) 612 | { 613 | parent = nodeBeingDeleted.Parent; 614 | } 615 | else 616 | { 617 | parent = ourNode.Parent; 618 | } 619 | 620 | GetParentGrandParentSibling(ourNode, parent, out sibling, out grandParent); 621 | 622 | if (ourNode != null && ourNode.Red) 623 | { 624 | ourNode.Red = false; 625 | } 626 | else if (!nodeToDeleteRed && !nodeBeingDeleted.Red) 627 | { 628 | FixAfterInsertion(ourNode, parent, sibling, grandParent); 629 | } 630 | 631 | root.Red = false; 632 | } 633 | } 634 | 635 | 636 | private void Case1(Node ourNode, Node parent, 637 | Node sibling, Node grandParent) 638 | { 639 | if (siblingToRight) 640 | { 641 | parent.Red = !parent.Red; 642 | sibling.Red = !sibling.Red; 643 | if (grandParent != null) 644 | { 645 | if (parentToRight) 646 | { 647 | LeftRotate(ref parent); 648 | grandParent.Left = parent; 649 | } 650 | else if (!parentToRight) 651 | { 652 | LeftRotate(ref parent); 653 | grandParent.Left = parent; 654 | } 655 | } 656 | else 657 | { 658 | LeftRotate(ref parent); 659 | root = parent; 660 | } 661 | grandParent = sibling; 662 | parent = parent.Left; 663 | parentToRight = false; 664 | } 665 | else if (!siblingToRight) 666 | { 667 | parent.Red = !parent.Red; 668 | sibling.Red = !sibling.Red; 669 | if (grandParent != null) 670 | { 671 | if (parentToRight) 672 | { 673 | RightRotate(ref parent); 674 | grandParent.Right = parent; 675 | } 676 | else if (!parentToRight) 677 | { 678 | RightRotate(ref parent); 679 | grandParent.Left = parent; 680 | } 681 | } 682 | else 683 | { 684 | RightRotate(ref parent); 685 | root = parent; 686 | } 687 | grandParent = sibling; 688 | parent = parent.Right; 689 | parentToRight = true; 690 | } 691 | 692 | if (parent.Right == ourNode) 693 | { 694 | sibling = parent.Left; 695 | siblingToRight = false; 696 | } 697 | else if (parent.Left == ourNode) 698 | { 699 | sibling = parent.Right; 700 | siblingToRight = true; 701 | } 702 | 703 | Node siblingLeftChild = null; 704 | Node siblingRightChild = null; 705 | 706 | if (sibling != null && sibling.Left != null) 707 | { 708 | siblingLeftChild = sibling.Left; 709 | } 710 | 711 | if (sibling != null && sibling.Right != null) 712 | { 713 | siblingRightChild = sibling.Right; 714 | } 715 | 716 | bool siblingRed = (sibling != null && sibling.Red); 717 | bool siblingLeftRed = (siblingLeftChild != null && siblingRightChild.Red); 718 | bool siblingRightRed = (siblingRightChild != null && siblingLeftChild.Red); 719 | 720 | if (parent.Red && !siblingRed && !siblingLeftRed && !siblingRightRed) 721 | { 722 | Case2B(ourNode, parent, sibling, grandParent); 723 | } 724 | else if (siblingToRight && !siblingRed && siblingLeftRed && !siblingRightRed) 725 | { 726 | Case3(ourNode, parent, sibling, grandParent); 727 | } 728 | else if (!siblingToRight && !siblingRed && !siblingLeftRed && siblingRightRed) 729 | { 730 | Case3P(ourNode, parent, sibling, grandParent); 731 | } 732 | else if (siblingToRight && !siblingRed && siblingRightRed) 733 | { 734 | Case4(ourNode, parent, sibling, grandParent); 735 | } 736 | else if (!siblingToRight && !siblingRed && siblingLeftRed) 737 | { 738 | Case4P(ourNode, parent, sibling, grandParent); 739 | } 740 | } 741 | 742 | private void Case2A(Node ourNode, Node parent, 743 | Node sibling, Node grandParent) 744 | { 745 | if (sibling != null) 746 | { 747 | sibling.Red = !sibling.Red; 748 | } 749 | ourNode = parent; 750 | if (ourNode != root) 751 | { 752 | parent = ourNode.Parent; 753 | GetParentGrandParentSibling(ourNode, parent, out sibling, out grandParent); 754 | 755 | Node siblingLeftChild = null; 756 | Node siblingRightChild = null; 757 | 758 | if (sibling != null && sibling.Left != null) 759 | { 760 | siblingLeftChild = sibling.Left; 761 | } 762 | if (sibling != null && sibling.Right != null) 763 | { 764 | siblingRightChild = sibling.Right; 765 | } 766 | 767 | bool siblingRed = (sibling != null && sibling.Red); 768 | bool siblingLeftRed = (siblingLeftChild != null && siblingLeftChild.Red); 769 | bool siblingRightRed = (siblingRightChild != null && siblingRightChild.Red); 770 | 771 | if (parent != null && !parent.Red && !siblingRed && !siblingLeftRed && !siblingRightRed) 772 | { 773 | Case2A(ourNode, parent, sibling, grandParent); 774 | } 775 | else if (parent != null && parent.Red && !siblingRed && !siblingLeftRed && !siblingRightRed) 776 | { 777 | Case2B(ourNode, parent, sibling, grandParent); 778 | } 779 | else if (siblingToRight && !sibling.Red && !siblingRed && siblingLeftRed && !siblingRightRed) 780 | { 781 | Case3(ourNode, parent, sibling, grandParent); 782 | } 783 | else if (!siblingToRight && !siblingRed && !siblingLeftRed && siblingRightRed) 784 | { 785 | Case3P(ourNode, parent, sibling, grandParent); 786 | } 787 | else if (siblingToRight && !siblingRed && siblingRightRed) 788 | { 789 | Case4(ourNode, parent, sibling, grandParent); 790 | } 791 | else if (!siblingToRight && !siblingRed && siblingLeftRed) 792 | { 793 | Case4P(ourNode, parent, sibling, grandParent); 794 | } 795 | } 796 | } 797 | 798 | private void Case2B(Node ourNode, Node parent, Node sibling, Node grandParent) 799 | { 800 | if (sibling != null) 801 | { 802 | sibling.Red = !sibling.Red; 803 | } 804 | ourNode = parent; 805 | ourNode.Red = !ourNode.Red; 806 | } 807 | 808 | private void Case3(Node ourNode, Node parent, Node sibling, Node grandParent) 809 | { 810 | if (parent.Left == ourNode) 811 | { 812 | sibling.Red = true; 813 | sibling.Left.Red = false; 814 | RightRotate(ref sibling); 815 | parent.Right = sibling; 816 | } 817 | Case4(ourNode, parent, sibling, grandParent); 818 | } 819 | 820 | private void Case3P(Node ourNode, Node parent, Node sibling, Node grandParent) 821 | { 822 | if (parent.Right == ourNode) 823 | { 824 | sibling.Red = true; 825 | sibling.Right.Red = false; 826 | LeftRotate(ref sibling); 827 | parent.Left = sibling; 828 | } 829 | Case4P(ourNode, parent, sibling, grandParent); 830 | } 831 | 832 | private void Case4(Node ourNode, Node parent, Node sibling, Node grandParent) 833 | { 834 | sibling.Red = parent.Red; 835 | sibling.Right.Red = false; 836 | parent.Red = false; 837 | 838 | if (grandParent != null) 839 | { 840 | if (parentToRight) 841 | { 842 | LeftRotate(ref parent); 843 | grandParent.Right = parent; 844 | } 845 | else 846 | { 847 | LeftRotate(ref parent); 848 | grandParent.Left = parent; 849 | } 850 | } 851 | else 852 | { 853 | LeftRotate(ref parent); 854 | root = parent; 855 | } 856 | } 857 | 858 | private void Case4P(Node ourNode, Node parent, Node sibling, Node grandParent) 859 | { 860 | sibling.Red = parent.Red; 861 | sibling.Left.Red = false; 862 | if (grandParent != null) 863 | { 864 | if (parentToRight) 865 | { 866 | RightRotate(ref parent); 867 | grandParent.Right = parent; 868 | } 869 | else 870 | { 871 | RightRotate(ref parent); 872 | grandParent.Left = parent; 873 | } 874 | } 875 | else 876 | { 877 | RightRotate(ref parent); 878 | root = parent; 879 | } 880 | } 881 | 882 | private void FixTreeAfterDeletion (Node ourNode, Node parent, Node sibling, Node grandParent) 883 | { 884 | Node siblingLeftChild = null; 885 | Node siblingRightChild = null; 886 | 887 | if (sibling != null && sibling.Left != null) 888 | { 889 | siblingLeftChild = sibling.Left; 890 | } 891 | 892 | if (sibling != null && sibling.Right != null) 893 | { 894 | siblingRightChild = sibling.Right; 895 | } 896 | 897 | bool siblingRed = (sibling != null && sibling.Red); 898 | bool siblingLeftRed = (siblingRightChild != null && siblingRightChild.Red); 899 | bool siblingRightRed = (siblingRightChild != null && siblingRightChild.Red); 900 | 901 | if (parent != null && !parent.Red && siblingRed && !siblingLeftRed && !siblingRightRed) 902 | { 903 | Case1(ourNode, parent, sibling, grandParent); 904 | } 905 | else if (parent != null && !parent.Red && !siblingRed && !siblingLeftRed && !siblingRightRed) 906 | { 907 | Case2A(ourNode, parent, sibling, grandParent); 908 | } 909 | else if (parent != null && parent.Red && !siblingRed && !siblingLeftRed && !siblingRightRed) 910 | { 911 | Case2B(ourNode, parent, sibling, grandParent); 912 | } 913 | else if (siblingToRight && !siblingRed && siblingLeftRed && !siblingRightRed) 914 | { 915 | Case3(ourNode, parent, sibling, grandParent); 916 | } 917 | else if (!siblingToRight && !siblingRed && !siblingLeftRed && siblingRightRed) 918 | { 919 | Case3P(ourNode, parent, sibling, grandParent); 920 | } 921 | else if (siblingToRight && !siblingRed && siblingRightRed) 922 | { 923 | Case4(ourNode, parent, sibling, grandParent); 924 | } 925 | else if (!siblingToRight && !siblingRed && siblingLeftRed) 926 | { 927 | Case4P(ourNode, parent, sibling, grandParent); 928 | } 929 | } 930 | 931 | } // Fim da Classe 932 | 933 | } // Fim namespace 934 | 935 | // http://www.jot.fm/issues/issue_2005_03/column6/ 936 | -------------------------------------------------------------------------------- /Data Structures/Sets/SortedSet/README.md: -------------------------------------------------------------------------------- 1 | # SortedSet 2 | A estrutura de SortedSet (Conjuntos Ordenados) permitem armazenar um conjunto de valores únicos ordenados de forma crescente, pelo seu valor natural - alfabético ou numérico - ou ordem especificada diretamente por um Objeto do tipo Comparator. Diferentemente do HashSet em que os elementos são ordenados conforme seu valor de Hash que por definição não conhecemos, o SortedSet guarda os elementos de forma ordenada, facilitando possiveis buscas que possam ser otimizadas por buscas ou métodos que possam beneficiar-se de ter os elementos ordenados (Ex: Um algoritmo que busca o nome de pessoas em uma lista telefônica cujo o nome inicie com uma letra entre M..Z do alfabeto). Apesar de seus itens estarem ordenados, é importante notar que o SortedSet é uma derivação de ISet e portanto é uma coleção que **não implementa índice**. 3 | 4 | A garantia de unicidade e organização de um SortedSet vem da implementação de uma Árvore Rubro-Negra que armazena em nós os objetos passados e os organiza, caso queira entender melhor sobre o algoritmo de Árvore Rubro-Negra em si você pode assistir este [vídeo](https://www.youtube.com/watch?v=DaWNuijRRFY) que explica sua lógica e funcionamento. 5 | 6 |
7 |
8 | 9 |
10 |
11 | Exemplo de representação do algoritmo de Árvore Binária Rubro-Negra que armazena os elementos. 12 |
13 |
14 |
15 | 16 | ## Implementação básica em C# 17 | A implementação do SortedSet depende da implementação da Árvore Rubro-Negra que foi implementada em C#, porém o foco do estudo neste tópico é a implementação do SortedSet e por isso não será estudado os detalhes da árvore, apesar de ser possivel estudá-la acessando o seu código fonte implementado nos arquivos. 18 | - [MySortedSet.cs](https://github.com/Camilotk/aprendendo_csharp/blob/master/Data%20Structures/Sets/SortedSet/Implementation/MySortedSet.cs) 19 | - [RedBlackTree.cs](https://github.com/Camilotk/aprendendo_csharp/blob/master/Data%20Structures/Sets/SortedSet/Implementation/RedBlackTree.cs) 20 | 21 | ## Imports 22 | **Linhas A a z** 23 | 24 | ... 25 | 26 | ```C# 27 | using System; 28 | ``` 29 | 30 | ### Propriedades 31 | **Linhas A a z** 32 | 33 | ... 34 | 35 | ```C# 36 | private RedBlackTree _elements { get; set; } 37 | ``` 38 | 39 | ### Método Construtor 40 | **Linhas A a z** 41 | 42 | ... 43 | 44 | ```C# 45 | public MySortedSet () => _elements = new RedBlackTree(); 46 | ``` 47 | 48 | ### Método .Add() 49 | **Linhas de A a z** 50 | 51 | ... 52 | 53 | ```C# 54 | try 55 | { 56 | _elements.Add(item); 57 | return true; 58 | } 59 | catch(Exception e) 60 | { 61 | Console.WriteLine(e.Message); 62 | return false; 63 | } 64 | ``` 65 | 66 | ### Método .Remove() 67 | **Linhas A..z** 68 | 69 | ... 70 | 71 | ```C# 72 | try 73 | { 74 | _elements.Remove(item); 75 | return true; 76 | } 77 | catch(Exception e) 78 | { 79 | Console.WriteLine(e.Message); 80 | return false; 81 | } 82 | ``` 83 | 84 | ## Exemplo de Uso 85 | ... 86 | 87 | ```C# 88 | // ... 89 | ``` 90 | **Output:** 91 | 92 | ``` 93 | // ... 94 | ``` 95 | # Referências 96 | 97 | - [ref](#) 98 | - [ref](#) 99 | - [ref](#) 100 | -------------------------------------------------------------------------------- /Data Structures/interfaces_csharp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Camilotk/aprendendo_csharp/29e161b6b4d7ef9155cfbd5aeac95cc726bc8fd7/Data Structures/interfaces_csharp.png -------------------------------------------------------------------------------- /Design Patterns/Observer/README.md: -------------------------------------------------------------------------------- 1 | # Observer Pattern 2 | 3 | -------------------------------------------------------------------------------- /Design Patterns/README.md: -------------------------------------------------------------------------------- 1 | # Padrões 2 | ## Principais 3 | - [ ] Abstract Factory 4 | - [ ] Adapter 5 | - [ ] Composite 6 | - [ ] Decorator 7 | - [ ] Factory Method 8 | - [ ] Observer 9 | - [X] Strategy 10 | - [ ] Template Method 11 | - [ ] View 12 | 13 | ## Outros 14 | - [ ] Facade 15 | - [ ] Mediator 16 | - [ ] Command 17 | - [ ] Active Object 18 | - [ ] Method 19 | - [ ] Singleton 20 | - [ ] Monostate 21 | - [ ] Bridge 22 | - [ ] Proxy 23 | - [ ] Gateway 24 | -------------------------------------------------------------------------------- /Design Patterns/Strategy/Calculadora.cs: -------------------------------------------------------------------------------- 1 | namespace strategyImposto 2 | { 3 | public class Calculadora 4 | { 5 | public double CalculaImposto(Orcamento orcamento, Imposto imposto) 6 | { 7 | double resultado = imposto.Calcula(orcamento); 8 | return resultado; 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /Design Patterns/Strategy/ICMS.cs: -------------------------------------------------------------------------------- 1 | namespace strategyImposto 2 | { 3 | public class ICMS : Imposto 4 | { 5 | public double Calcula(Orcamento orcamento) 6 | { 7 | return orcamento.valor * 0.1; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Design Patterns/Strategy/ISS.cs: -------------------------------------------------------------------------------- 1 | namespace strategyImposto 2 | { 3 | public class ISS : Imposto 4 | { 5 | public double Calcula(Orcamento orcamento) 6 | { 7 | return orcamento.valor * 0.06; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Design Patterns/Strategy/Imposto.cs: -------------------------------------------------------------------------------- 1 | namespace strategyImposto 2 | { 3 | public interface Imposto 4 | { 5 | double Calcula(Orcamento orcamento); 6 | } 7 | } -------------------------------------------------------------------------------- /Design Patterns/Strategy/Orcamento.cs: -------------------------------------------------------------------------------- 1 | namespace strategyImposto 2 | { 3 | public class Orcamento 4 | { 5 | public double valor { get; private set; } 6 | 7 | public Orcamento(double Valor) 8 | { 9 | this.valor = Valor; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Design Patterns/Strategy/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace strategyImposto 4 | { 5 | class Program 6 | { 7 | static void Main(string[] args) 8 | { 9 | Imposto icms = new ICMS(); 10 | Imposto iss = new ISS(); 11 | 12 | Orcamento orcamento = new Orcamento(500); 13 | 14 | Console.WriteLine(iss.Calcula(orcamento)); 15 | 16 | Console.WriteLine(icms.Calcula(orcamento)); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Design Patterns/Strategy/README.md: -------------------------------------------------------------------------------- 1 | # Strategy Pattern 2 | *Tipo*: Padrão Comportamental
3 | O padrão Strategy tenta reduzir o acoplamento de uma família de algorítmos com comportamento similares e fazer com que sejam intercambiaveis entre si.
4 |
5 | O Padrão Strategy sugere que se produza uma família de classes para cada variação do algoritmo e que se forneça para a classe hospedeira uma instância de Strategy para a qual ela delegará em tempo de execução. Um dos pré-requisitos para o Strategy é uma estrutura de herança onde cada subclasse específica contém uma variação do algoritmo. Assim, o padrão Strategy possui diversos benefícios como clarificar algoritmos ao diminuir ou remover lógica condicional, simplificar uma classe ao mover variações de um algoritmo para uma hierarquia, e habilitar um algoritmo para ser substituído por outro em tempo de execução. 6 | 7 | ## Motivação 8 | Em resumo o padrão Strategy pode ser utilizado quando se tem as seguintes situações: 9 | 10 | Quando muitas classes relacionadas diferem apenas no seu comportamento; 11 |
12 | * Quando necessita-se de variantes de um algoritmo; 13 | * Quando se precisa ocultar do usuário a exposição das estruturas de dados complexas, específicas do algoritmo; 14 | * Quando uma classe define muitos comportamentos e por sua vez eles aparecem como diversos “IFs”. Com isso esses comandos condicionais são movidos para sua própria classe Strategy. 15 | 16 | ## Links 17 | [Medium - Mulheres de Produto - O que é Strategy Pattern?](https://medium.com/mulheres-de-produto/o-que-%C3%A9-strategy-pattern-e-quando-usar-2fc3bcb4873f)
18 | [Estudo e Aplicação do Padrão de Projeto Strategy](https://www.devmedia.com.br/estudo-e-aplicacao-do-padrao-de-projeto-strategy/25856)
19 | [Using the Strategy Pattern (Examples in C#)](https://dev.to/sam_ferree/using-the-strategy-pattern-examples-in-c-4jn6) 20 | 21 | ## Aula 22 | 23 | [![Design Patterns 1](http://img.youtube.com/vi/Z2ScCR1tyzU/0.jpg)](http://www.youtube.com/watch?v=Z2ScCR1tyzU) 24 | 25 | ![UML Startegy Pattern](https://github.com/Camilotk/csharp/blob/master/Design%20Patterns/Strategy/uml.png "UML Startegy Pattern") 26 | 27 | ### Classes da Aula 28 | * [Program](https://github.com/Camilotk/csharp/blob/master/Design%20Patterns/Strategy/Program.cs): Classe Main, onde o código é executado. 29 | * [Orcamento](https://github.com/Camilotk/csharp/blob/master/Design%20Patterns/Strategy/Orcamento.cs): Classe que abstrai o orçamento, possuindo o atributo _double_ valor e os métodos _get_ e _set_ do mesmo. 30 | * [Imposto](https://github.com/Camilotk/csharp/blob/master/Design%20Patterns/Strategy/Imposto.cs): Interface que faz o contrato da função _Calcula_ que obriga que todos os que implementam-na possam ser usados como paramêtro através de Polimorfismo em métodos de outras classes. 31 | * [Calculadora](https://github.com/Camilotk/csharp/blob/master/Design%20Patterns/Strategy/Calculadora.cs): Classe que possui o método _CalculaImposto_ responsável por receber um objeto _Orcamento_ e uma implementação da interface _Imposto_ e devolver o cálculo realizado dentro da classe específica. 32 | * [ICMS](https://github.com/Camilotk/csharp/blob/master/Design%20Patterns/Strategy/ICMS.cs) e [ISS](https://github.com/Camilotk/csharp/blob/master/Design%20Patterns/Strategy/ISS.cs): Implementações de diferentes impostos (família de tarefas). 33 | -------------------------------------------------------------------------------- /Design Patterns/Strategy/uml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Camilotk/aprendendo_csharp/29e161b6b4d7ef9155cfbd5aeac95cc726bc8fd7/Design Patterns/Strategy/uml.png -------------------------------------------------------------------------------- /ENTITY.md: -------------------------------------------------------------------------------- 1 | # Entity Framework Core 2 | O Entity Framework Core é a ferramente de criação, edição e manipulação de Banco de Dados por ORM [¹](https://pt.stackoverflow.com/a/138943) do .NET Core. Podemos utilizar o Entity Framework Core para trabalhar com qualquer base de dados, seja ela SQLServer, MariaDB, Oracle, SQLite, PostgreSQL ou MYSQL utilizando o mesmo fluxo de trabalho e utilizando-se de abstrações do mais alto nível para transformar o modelo orientado à objetos do projeto em relações na Base de Dados, todo esse trabalho é feito pelo Framework, permitindo que o programador preocupe-se mais com a modelagem do projeto orientado à objetos e menos com a Base de Dados que está utilizando. 3 | 4 | ## Tutorial 5 | 1. Para utilizar o Entity, primeiro devemos criar um Projeto, caso ainda não tenha feito-o, basta utilizar o comando **dotnet new** para isso. 6 | ``` 7 | dotnet new console -o TesteEntity 8 | ``` 9 | 2. Acessar o Diretório do Projeto 10 | ```bash 11 | cd ConsoleApp 12 | ``` 13 | 3. Para usar o EF Core, instale o pacote do provedor do banco de dados para o qual você deseja direcionar, cada banco possui um pacote diferente para fazer a conexão, no caso do Postgres usamos o npgsql. Caso tenha dúvidas sobre como instalar um pacote no projeto pode acessar o Tutorial do [NuGET](https://github.com/Camilotk/aprendendo_csharp/blob/master/NUGET.md) aqui. 14 | ``` 15 | dotnet add package Microsoft.EntityFrameworkCore.Design 16 | dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL 17 | dotnet add package Microsoft.EntityFrameworkCore.Tools 18 | ``` 19 | 4. Confira no arquivo *.csproj* se as seguintes referências foram adicionadas. 20 | ```xml 21 | 22 | 23 | 24 | 25 | runtime; build; native; contentfiles; analyzers; buildtransitive 26 | all 27 | 28 | 29 | 30 | ``` 31 | 5. Crie uma Classe *Context* que contêm as configurações de acesso e tabelas do banco. 32 | 33 |

BloggingContext.cs

34 | 35 | ```C# 36 | using Microsoft.EntityFrameworkCore; 37 | 38 | namespace TesteEntity 39 | { 40 | /* 41 | * DbContext é uma classe central do Entity Framework. Ela representa uma 42 | * abstração do banco de dados dentro da aplicação e é por meio dela que 43 | * acessamos as tabelas (na forma de listas) e os registros (na forma de 44 | * objetos). 45 | */ 46 | public class BloggingContext : DbContext 47 | { 48 | /* 49 | * A classe DbSet representa uma coleção de objetos que será mapeada 50 | * como registros do banco de dados. 51 | * Cada DbSet representa uma tabela que será mapeada no Banco de Dados 52 | * neste caso teremos as tabelas: Blogs e Posts 53 | */ 54 | public DbSet Blogs { get; set; } 55 | public DbSet Posts { get; set; } 56 | 57 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 58 | => optionsBuilder.UseNpgsql("Host=localhost;Port=5432;Database=NOME_DATABASE;Username=postgres;Password=XXXX"); 59 | } 60 | } 61 | ``` 62 | 6. Crie as Classes que representam a abstração dos dados que serão adicionados nas Tabelas. 63 | 64 |

Blog.cs

65 | 66 | ```C# 67 | using System.Collections.Generic; 68 | 69 | namespace TesteEntity 70 | { 71 | public class Blog 72 | { 73 | /* 74 | * A propriedade BlogId será usada como chave primária da tabela que será 75 | * gerada no banco. Essa nomenclatura é >reconhecida por padrão pelo 76 | * Entity Framework e em seu lugar poderia ser usado Id 77 | */ 78 | public int BlogId { get; set; } 79 | // Propriedade que armazena a URL 80 | public string Url { get; set; } 81 | 82 | // Uma Lista de Objetos Posts 83 | public ICollection Posts { get; set; } 84 | } 85 | } 86 | ``` 87 | **Post.cs**
88 | ```C# 89 | namespace TesteEntity 90 | { 91 | public class Post 92 | { 93 | public int PostId { get; set; } 94 | public string Title { get; set; } 95 | public string Content { get; set; } 96 | 97 | public int BlogId { get; set; } 98 | public Blog Blog { get; set; } 99 | } 100 | } 101 | ``` 102 | 5. Criar as migrações (_migrations_)[²](https://docs.microsoft.com/pt-br/ef/core/managing-schemas/migrations/index) para criar e atualizar o banco de dados. 103 | 104 |

Cria o banco e tabelas

105 | 106 | ``` 107 | dotnet ef migrations add InitialCreate 108 | ``` 109 | *Aplica as atualizações*
110 | ``` 111 | dotnet ef database update 112 | ``` 113 | 6. Criar o **Main.cs** onde iremos executar algumas inserções e buscas no Banco. 114 |

Main.cs

115 | 116 | ```C# 117 | using System; 118 | 119 | namespace TesteEntity 120 | { 121 | public class Program 122 | { 123 | public static void Main() 124 | { 125 | using (var db = new BloggingContext()) 126 | { 127 | 128 | // Adiciona um novo Objeto Blog à collection Blogs, isso depois 129 | // é mapeado no ORM transformando a Collectione em Tabela e o 130 | // Objeto em Input 131 | db.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/adonet" }); 132 | // Salva as mudanças 133 | var count = db.SaveChanges(); 134 | Console.WriteLine("{0} records saved to database", count); 135 | 136 | Console.WriteLine(); 137 | // Acessa a lista de Blogs e retorna o endereço 138 | Console.WriteLine("All blogs in database:"); 139 | foreach (var blog in db.Blogs) 140 | { 141 | Console.WriteLine(" - {0}", blog.Url); 142 | } 143 | } 144 | } 145 | } 146 | } 147 | ``` 148 | 149 | 7. Executar o comando **dotnet run** e ver se teve a saída de acordo.
150 | ``` 151 | dotnet run 152 | ``` 153 | 154 | **Saída:** 155 |
156 | 157 | ``` 158 | ConsoleApp.SQLite>dotnet run 159 | 1 records saved to database 160 | 161 | All blogs in database: 162 | - http://blogs.msdn.com/adonet 163 | ``` 164 | ## Referências 165 | - [Introdução ao EF Core no aplicativo de console do .NET Core com um novo banco de dados (SQLite)](https://docs.microsoft.com/pt-br/ef/core/get-started/netcore/new-db-sqlite) 166 | - [Npgsql - Getting Started (Postgres)](http://www.npgsql.org/efcore/) 167 | - [ASP.NET Core Application to New Database (SQLServer)](https://ef.readthedocs.io/en/staging/platforms/aspnetcore/new-db.html) 168 | -------------------------------------------------------------------------------- /INSTALLATION.md: -------------------------------------------------------------------------------- 1 | ## Instalação no VSCode 2 | 1. Baixar a SDK para o sistema operacional desejado. [link para download](https://dotnet.microsoft.com/download) 3 | 1. Instalar o VSCode. [link para download](https://code.visualstudio.com/) 4 | 1. Instalar as extensões: [C#](https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp) e [C# extensions](https://marketplace.visualstudio.com/items?itemName=jchannon.csharpextensions) 5 | 1. Aqui já está OK para trabalhar, mas podemos intalar algumas ferramentas adicionais. Caso queira apenas começar a programar: *Está Pronto!* 6 | ### Ferramentas adicionais 7 | 1. Caso, esteja no Windows, instale o [Chocolatey](https://en.wikipedia.org/wiki/NuGet#Chocolatey) e use-o para instalar os pacotes de desenvolvimento. [Instalação](https://chocolatey.org/install#installing-chocolatey) e [Comandos](https://chocolatey.org/docs/commandslist) 8 | 1. Instale o node (é necessário para compilar qualquer projeto Web ASP.NET) 9 | ``` 10 | choco install nodejs 11 | ``` 12 | 3. Faça o update e instale as depdências básicas. 13 | ``` 14 | npm install -g npm 15 | npm i -g yarn gulp 16 | ``` 17 | -------------------------------------------------------------------------------- /MSTEST.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /NUGET.md: -------------------------------------------------------------------------------- 1 | # .NET Core Package Manager .NuGET 2 | Com frequência, durante o desenvolvimento das nossas aplicações, precisamos instalar pacotes de terceiros para realizar as mais diversas tarefas, como acesso a bancos de dados, validações, etc. 3 | 4 | Antes do NuGet esse procedimento era feito de forma manual, ou seja, precisávamos realizar nos sites dos desenvolvedores o download das bibliotecas e incluí-las em nossos projetos. Quando uma nova versão era lançada, era preciso baixá-la novamente e substituir em todos os locais em que ela estivesse sendo usada. 5 | 6 | Com o NuGet esse procedimento é simplificado. Todas as bibliotecas ficam centralizadas no repositório nuget.org e por meio de uma ferramenta é possível instalar, atualizar e remover os pacotes de forma bastante prática. 7 | 8 | Quando instalamos um pacote em nossa aplicação o NuGet o registra no arquivo *.csproj*, semelhante ao pom.xml do Maven, composer.json do Composer e package.json do NPM. A partir desse arquivo podemos reinstalar com facilidade todos os pacotes posteriormente. 9 | 10 | ## Pré-requesitos 11 | - O SDK do .NET Core, que fornece a ferramenta de linha de comando dotnet. [Baixar Aqui](https://dotnet.microsoft.com/download) 12 | 13 | ## Commandos e Utilização 14 | ### Instalando Pacote 15 | 1. Entrar na pasta do _projeto_ em que o pacote será instalado. 16 | 2. Dentro da pasta, utilizar o CLI do .NET para instalar o pacote desejado. 17 | ``` 18 | dotnet add package -v=1.0.1 19 | dotnet add package --version=1.0.1 20 | ``` 21 | 3. Após a conclusão do comando, abra o arquivo *.csproj* para ver a referência adicionada. 22 | ```XML 23 | 24 | 25 | 26 | ``` 27 | 4. Ao executar o comando **dotnet run** ou **dotnet build**, automaticamente, em primeiro lugar será checado o arquivo .csproj e as depedências serão atualizadas. 28 | ### Atualizando Pacote 29 | - Para fazer o Update de um pacote basta rodar o comando **dotnet add** com o nome do pacote sem a _flag_ --version (-v) ou especificando para qual versão quer fazer o upograde/downgrade 30 | ### Removendo Pacote 31 | 1. Entrar na pasta do _projeto_ em que o pacote será removido. 32 | 2. Dentro da pasta, utilizar o CLI do .NET para remover o pacote desejado. 33 | ``` 34 | dotnet remove package 35 | dotnet remove package 36 | ``` 37 | 3. Após a conclusão do comando, abra o arquivo *.csproj* para ver a referência foi removida. 38 | 4. Ao executar o comando **dotnet run** ou **dotnet build**, automaticamente, em primeiro lugar será checado o arquivo .csproj e as depedências serão atualizadas. 39 | ## Referências 40 | - [Quickstart do Nuget CLI: How to Install and Use a Package](https://docs.microsoft.com/pt-br/nuget/quickstart/install-and-use-a-package-using-the-dotnet-cli) 41 | - [Artigo: How to Update a Nuget Package using CLI](https://ardalis.com/how-do-i-update-a-nuget-package-using-dotnet-cli) 42 | - [Documentação Remove Package](https://docs.microsoft.com/pt-br/dotnet/core/tools/dotnet-remove-package) 43 | -------------------------------------------------------------------------------- /POWERSHELL.md: -------------------------------------------------------------------------------- 1 | ## Utilizando os comandos por Powershell 2 | Quando utilizamos o VSCode para programar em C#, também utilizamos juntamente o Terminal para gerenciar os projetos e depedências. 3 | 4 | | Comando | O que faz? | opc | param. | 5 | |----------------------------------------------------------------------------------------|-------------------|---------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 6 | | dotnet new -o
dotnet new -l
dotnet new -lang F# -o | Cria novo projeto | | -o nome do projeto
-l lista de templates
-lang | 7 | | dotnet build | Compila o projeto | | dotnet build -v - verbosidade
dotnet build -o - Caminho do .exe

dotnet build --runtime
ex: dotnet build --runtime ubuntu.18.04-x64

dotnet build --source
ex: dotnet build --source c:\packages\mypackages | 8 | | dotnet run | Roda o projeto | | dotnet run --project ./projects/proj1/proj1.csproj | 9 | 10 | ## Powershell 11 | Por isso, também é útil saber um pouco de como utilizar o Powershell do Windows. Caso utilize Mac ou Linux, pode-se instalar o Powershell e utilizá-lo ou então utilizar o terminal nativo com Bash (que é melhor). 12 |

13 | ![Powershell commands](https://github.com/Camilotk/csharp/blob/master/ps-cheatsheet.jpeg "Comandos Powershell") 14 | [PDF Ver.](https://cdn.comparitech.com/wp-content/uploads/2018/08/Comparitech-Powershell-cheatsheet.pdf) 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Apredendo C# 2 | [![License: CC BY 4.0](https://img.shields.io/badge/License-CC%20BY%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by/4.0/) 3 | [![made-for-VSCode](https://img.shields.io/badge/Made%20for-VSCode-1f425f.svg)](https://code.visualstudio.com/) 4 | [![Ask Me Anything !](https://img.shields.io/badge/Ask%20me-anything-1abc9c.svg)](https://github.com/Camilotk/teste_skeel/issues/new) 5 | 6 | Em certo momento surgiu a necessidade de que eu aprendesse C#, tanto para a utilização com a API de programas 3D que eu já utilizo, quanto para que eu conseguisse ministrar aulas de Unity, vagas de emprego e para trabalhos da faculdade. Criei esse repositório para armazenar as informações que preciso e exemplos de código durante a transição para a plataforma .NET. A ideia principal deste repositório é servir como uma **fonte aberta, gratuita e comunitária de informações em português sobre a programação em C#** e principalmente de suas implementações multiplataforma (.NET Core e Mono). 7 | 8 | As principais inspirações desse projeto é a Open Source Society University (OSSU)[1](https://github.com/ossu/computer-science) e os Open Curriculums[2](https://github.com/llSourcell/Learn_Machine_Learning_in_3_Months) de Data Science, Ciência da Computação e Blockchain do Professor Siraj Raval. Espero que o material seja útil à todos, qualquer dúvida, sugestão ou pedido pode ser adicionado no campo de Issues e qualquer correção, adição ou revisão pode ser feita através de Pull Request a ajuda e feedback de todos não é somente bem-vinda, quanto necessária para manter a qualidade, consistência e coesão do conteúdo. 9 | 10 | ## Sumário 11 | ### Instalação, Pacotes e Configuração de Ambiente 12 | - [Instalando o Ambiente de Desenvolvimento (VSCode)](https://github.com/Camilotk/aprendendo_csharp/blob/master/INSTALLATION.md) 13 | - [Utilizando os comandos do Powershell](https://github.com/Camilotk/aprendendo_csharp/blob/master/POWERSHELL.md) 14 | - [Nuget](https://github.com/Camilotk/aprendendo_csharp/blob/master/NUGET.md) 15 | - [C# REPL](https://github.com/scriptcs/scriptcs)* 16 | ### Banco de Dados 17 | - [Entity Framework Core](https://github.com/Camilotk/aprendendo_csharp/blob/master/ENTITY.md) 18 | - [Dapper](#)* 19 | - [LINQ](#)* 20 | ### Algoritmos e Estrutura de Dados 21 | - [Algoritmos](#)* 22 | - [Estrutura de Dados](https://github.com/Camilotk/aprendendo_csharp/tree/master/Data%20Structures) 23 | ### SOLID, Principios de OO e Design Patterns 24 | - [Principios de OO](#) 25 | - [SOLID](https://github.com/Camilotk/aprendendo_csharp/tree/master/SOLID) 26 | - [Design Patterns](https://github.com/Camilotk/aprendendo_csharp/tree/master/Design%20Patterns) 27 | ### TDD e Testes 28 | - [MSTest](#) 29 | - [XUnit](#) 30 | - [TDD](#) 31 | ### ASP.NET Core 32 | - [ASP.net Core](https://docs.microsoft.com/pt-br/aspnet/core/?view=aspnetcore-2.2) 33 | - [Blazor](#) 34 | ### Xamarin 35 | - [Mono](#) 36 | - [Xamarin](https://docs.microsoft.com/pt-br/xamarin/cross-platform/get-started/) 37 | ### Arquitetura 38 | - [MVP](#) 39 | - [MVC](#) 40 | - [MVVM](#) 41 | ### Machine Learning 42 | - [SciSharp](https://github.com/SciSharp) 43 | - [.NET ML](#) 44 | ### Blockchain 45 | - [Blockchain](https://www.c-sharpcorner.com/article/blockchain-basics-building-a-blockchain-in-net-core/) 46 | 47 | -------------------------------------------------------------------------------- /SOLID/README.md: -------------------------------------------------------------------------------- 1 | # Principios SOLID 2 | 3 | - [ ] Single responsibility principle 4 | - [ ] Open/closed principle 5 | - [ ] Liskov substitution principle 6 | - [ ] Interface segregation principle 7 | - [ ] Dependency inversion principle 8 | -------------------------------------------------------------------------------- /dump/Blog.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TesteEntity 4 | { 5 | public class Blog 6 | { 7 | /* 8 | * A propriedade BlogId será usada como chave primária da tabela que será 9 | * gerada no banco. Essa nomenclatura é >reconhecida por padrão pelo 10 | * Entity Framework e em seu lugar poderia ser usado Id 11 | */ 12 | public int BlogId { get; set; } 13 | // Propriedade que armazena a URL 14 | public string Url { get; set; } 15 | 16 | // Uma Lista de Objetos Posts 17 | public ICollection Posts { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /dump/BloggingContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | // Tutorial: https://docs.microsoft.com/pt-br/ef/core/get-started/netcore/new-db-sqlite 4 | // Tutorial: http://www.npgsql.org/efcore/ 5 | // Tutorial: https://ef.readthedocs.io/en/staging/platforms/aspnetcore/new-db.html 6 | 7 | namespace TesteEntity 8 | { 9 | /* 10 | * DbContext é uma classe central do Entity Framework. Ela representa uma 11 | * abstração do banco de dados dentro da aplicação e é por meio dela que 12 | * acessamos as tabelas (na forma de listas) e os registros (na forma de 13 | * objetos). 14 | */ 15 | public class BloggingContext : DbContext 16 | { 17 | /* 18 | * A classe DbSet representa uma coleção de objetos que será mapeada 19 | * como registros do banco de dados. 20 | * Cada DbSet representa uma tabela que será mapeada no Banco de Dados 21 | * neste caso teremos as tabelas: Blogs e Posts 22 | */ 23 | public DbSet Blogs { get; set; } 24 | public DbSet Posts { get; set; } 25 | 26 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 27 | => optionsBuilder.UseNpgsql("Host=localhost;Port=5432;Database=efcore_test;Username=postgres;Password=3001"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /dump/DatabaseMain.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TesteEntity 4 | { 5 | public class Program 6 | { 7 | public static void Main() 8 | { 9 | using (var db = new BloggingContext()) 10 | { 11 | 12 | // Adiciona um novo Objeto Blog à collection Blogs, isso depois 13 | // é mapeado no ORM transformando a Collectione em Tabela e o 14 | // Objeto em Input 15 | db.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/adonet" }); 16 | // Salva as mudanças 17 | var count = db.SaveChanges(); 18 | Console.WriteLine("{0} records saved to database", count); 19 | 20 | Console.WriteLine(); 21 | // Acessa a lista de Blogs e retorna o endereço 22 | Console.WriteLine("All blogs in database:"); 23 | foreach (var blog in db.Blogs) 24 | { 25 | Console.WriteLine(" - {0}", blog.Url); 26 | } 27 | } 28 | } 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /dump/Post.cs: -------------------------------------------------------------------------------- 1 | namespace TesteEntity 2 | { 3 | public class Post 4 | { 5 | public int PostId { get; set; } 6 | public string Title { get; set; } 7 | public string Content { get; set; } 8 | 9 | public int BlogId { get; set; } 10 | public Blog Blog { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /dump/Primeiro.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace myProgram 4 | { 5 | class Program 6 | { 7 | static void Main(string[] args) 8 | { 9 | // Criar var 10 | string name = "Camilo"; 11 | // Ler int do teclado 12 | Console.Write("Digite sua idade: "); 13 | int idade = Convert.ToInt16(Console.ReadLine()); 14 | // Interpolação de var por ordem de parâmetro. 15 | Console.WriteLine("Olá {0}, seja bem-vindo ao C#!", name); 16 | // Interpolação por nome da var. 17 | Console.WriteLine($"Você tem {idade}"); 18 | // Print arguments. 19 | Console.WriteLine($"0: {args[0]} 1: {args[1]}"); 20 | 21 | // Ex. 22 | Console.WriteLine($"Você terá {idade + 5} em {System.DateTime.Now.Year + 5}!"); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ps-cheatsheet.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Camilotk/aprendendo_csharp/29e161b6b4d7ef9155cfbd5aeac95cc726bc8fd7/ps-cheatsheet.jpeg --------------------------------------------------------------------------------