C # é uma linguagem de programação moderna, de uso geral e orientada a objetos desenvolvida pela Microsoft. C # foi projetado para Common Language Infrastructure (CLI), que consiste no código executável e no ambiente de tempo de execução que permite o uso de várias linguagens de alto nível em diferentes plataformas e arquiteturas de computador.

Uma matriz Jagged é uma matriz de matrizes.

Você pode inicializar uma matriz denteada como -

int[][] scores = new int[2][]{new int[]{92,93,94},new int[]{85,66,87,88}};

Onde, scores é uma matriz de duas matrizes de inteiros - scores [0] é uma matriz de 3 inteiros e scores [1] é uma matriz de 4 inteiros.

Existem três maneiras de passar parâmetros para um método -

  • Value parameters- Este método copia o valor real de um argumento para o parâmetro formal da função. Nesse caso, as alterações feitas no parâmetro dentro da função não afetam o argumento.

  • Reference parameters- Este método copia a referência ao local da memória de um argumento para o parâmetro formal. Isso significa que as alterações feitas no parâmetro afetam o argumento.

  • Output parameters - Este método ajuda a retornar mais de um valor.

Sim! Usando parâmetros de saída. Uma instrução de retorno pode ser usada para retornar apenas um valor de uma função. No entanto, usando parâmetros de saída, você pode retornar dois valores de uma função.

Os parâmetros de saída são semelhantes aos parâmetros de referência, exceto que eles transferem dados fora do método em vez de dentro dele. O parâmetro de referência copia a referência ao local da memória de um argumento para o parâmetro formal. Isso significa que as alterações feitas no parâmetro afetam o argumento.

Um namespace é projetado para fornecer uma maneira de manter um conjunto de nomes separado de outro. Os nomes de classe declarados em um namespace não entram em conflito com os mesmos nomes de classe declarados em outro.

using keyword é usado para incluir um namespace no programa. Um programa geralmente possui várias instruções using.

Variáveis ​​de tipo de valor podem ser atribuídas a um valor diretamente. Eles são derivados da classe System.ValueType.

Os tipos de valor contêm dados diretamente. Alguns exemplos são int, char e float, que armazenam números, alfabetos e números de ponto flutuante, respectivamente. Quando você declara um tipo int, o sistema aloca memória para armazenar o valor.

Os tipos de referência não contêm os dados reais armazenados em uma variável, mas contêm uma referência às variáveis.

Em outras palavras, eles se referem a um local de memória. Usando várias variáveis, os tipos de referência podem se referir a um local de memória. Se os dados na localização da memória forem alterados por uma das variáveis, a outra variável refletirá automaticamente essa alteração no valor. Exemplos de tipos de referência integrados são: objeto, dinâmico e string.

O Object Type é a classe base definitiva para todos os tipos de dados no C # Common Type System (CTS). Object é um alias para a classe System.Object. Os tipos de objetos podem ser atribuídos a valores de quaisquer outros tipos, tipos de valor, tipos de referência, tipos predefinidos ou definidos pelo usuário. Porém, antes de atribuir valores, ele precisa de conversão de tipo.

Quando um tipo de valor é convertido em tipo de objeto, é denominado boxing.

Quando um tipo de objeto é convertido em um tipo de valor, ele é chamado de unboxing.

Você pode armazenar qualquer tipo de valor na variável de tipo de dados dinâmico. A verificação de tipo para esses tipos de variáveis ​​ocorre em tempo de execução.

A sintaxe para declarar um tipo dinâmico é -

dynamic <variable_name> = value;

Por exemplo,

dynamic d = 20;

Os tipos dinâmicos são semelhantes aos tipos de objeto, exceto que a verificação de tipo para variáveis ​​de tipo de objeto ocorre em tempo de compilação, enquanto que para as variáveis ​​de tipo dinâmico ocorre em tempo de execução.

Variáveis ​​de tipo de ponteiro armazenam o endereço de memória de outro tipo. Os ponteiros em C # têm os mesmos recursos que os ponteiros em C ou C ++.

A sintaxe para declarar um tipo de ponteiro é -

type* identifier;

Por exemplo

char* cptr;
int* iptr;

Este operador determina se um objeto é de um determinado tipo.

If (Ford is Car) // verifica se Ford é um objeto da classe Car.

como o operador lança sem levantar uma exceção se a conversão falhar.

Object obj = new StringReader("Hello");
StringReader r = obj as StringReader;

O encapsulamento é definido 'como o processo de encerrar um ou mais itens em um pacote físico ou lógico'. O encapsulamento, na metodologia de programação orientada a objetos, impede o acesso aos detalhes de implementação.

O encapsulamento é implementado usando especificadores de acesso.

Um especificador de acesso define o escopo e a visibilidade de um membro da classe.

O especificador de acesso público permite que uma classe exponha suas variáveis ​​de membro e funções de membro a outras funções e objetos. Qualquer membro público pode ser acessado de fora da classe.

O especificador de acesso privado permite que uma classe oculte suas variáveis ​​de membro e funções de membro de outras funções e objetos. Apenas funções da mesma classe podem acessar seus membros privados. Mesmo uma instância de uma classe não pode acessar seus membros privados.

O especificador de acesso protegido permite que uma classe filha acesse as variáveis ​​de membro e funções de membro de sua classe base. Desta forma, ajuda na implementação de herança.

O especificador de acesso interno permite que uma classe exponha suas variáveis ​​de membro e funções de membro a outras funções e objetos no assembly atual. Em outras palavras, qualquer membro com especificador de acesso interno pode ser acessado de qualquer classe ou método definido no aplicativo no qual o membro está definido.

O especificador de acesso interno protegido permite que uma classe oculte suas variáveis ​​de membro e funções de membro de outros objetos e funções de classe, exceto uma classe filha dentro do mesmo aplicativo. Isso também é usado durante a implementação de herança.

C # fornece tipos de dados especiais, os tipos anuláveis, aos quais você pode atribuir uma faixa normal de valores, bem como valores nulos.

Por exemplo, você pode armazenar qualquer valor de -2.147.483.648 a 2.147.483.647 ou nulo em uma variável Nullable <Int32>. Da mesma forma, você pode atribuir verdadeiro, falso ou nulo em uma variável Nullable <bool>.

O operador de coalescência nulo é usado com os tipos de valor anulável e tipos de referência. É usado para converter um operando para o tipo de outro operando do tipo valor anulável (ou não), onde uma conversão implícita é possível.

Se o valor do primeiro operando for nulo, o operador retorna o valor do segundo operando, caso contrário, retorna o valor do primeiro operando.

Usando a palavra-chave params, um parâmetro de método pode ser especificado que leva um número variável de argumentos ou mesmo nenhum argumento.

Não! parâmetros adicionais não são permitidos após a palavra-chave params em uma declaração de método. Apenas uma palavra-chave params é permitida em uma declaração de método.

A classe Array é a classe base para todos os arrays em C #. Ele é definido no namespace System. A classe Array fornece várias propriedades e métodos para trabalhar com arrays.

Usando a função Array.sort (array). Ele classifica os elementos em um Array unidimensional inteiro usando a implementação IComparable de cada elemento do Array.

Primeiro classifique a matriz usando Array.sort (array) e depois inverta o mesmo usando o método Array.reverse (array).

Em C #, uma estrutura é um tipo de dados de tipo de valor. Ajuda a fazer com que uma única variável contenha dados relacionados de vários tipos de dados. A palavra-chave struct é usada para criar uma estrutura.

As estruturas são usadas para representar um registro. Para definir uma estrutura, você deve usar a instrução struct. A instrução struct define um novo tipo de dados, com mais de um membro para seu programa.

Classes e estruturas têm as seguintes diferenças básicas -

  • classes são tipos de referência e structs são tipos de valor.

  • estruturas não suportam herança.

  • estruturas não podem ter construtor padrão.

Uma enumeração é um conjunto de constantes inteiras nomeadas. Um tipo enumerado é declarado usando a palavra-chave enum.

Enumerações C # são tipos de dados de valor. Em outras palavras, a enumeração contém seus próprios valores e não pode herdar ou transmitir herança.

O especificador de acesso padrão para um tipo de classe é interno.

O acesso padrão para os membros é privado.

Um dos conceitos mais importantes na programação orientada a objetos é a herança. A herança nos permite definir uma classe em termos de outra classe, o que torna mais fácil criar e manter um aplicativo. Isso também oferece uma oportunidade de reutilizar a funcionalidade do código e acelera o tempo de implementação.

Ao criar uma classe, em vez de escrever membros de dados e funções de membro completamente novos, o programador pode designar que a nova classe deve herdar os membros de uma classe existente. Essa classe existente é chamada de classe base e a nova classe é chamada de classe derivada.

A ideia de herança implementa o relacionamento IS-A. Por exemplo, o mamífero É um animal, o cão é um mamífero, portanto, o cão também é um animal e assim por diante.

Não! C # não oferece suporte a herança múltipla.

Uma classe pode ser derivada de mais de uma classe ou interface, o que significa que ela pode herdar dados e funções de várias classes base ou interfaces. A sintaxe usada em C # para criar classes derivadas é a seguinte -

<acess-specifier> class <base_class>
{
   ...
}
class <derived_class> : <base_class>
{
   ...
}

A palavra polimorfismo significa ter muitas formas. No paradigma da programação orientada a objetos, o polimorfismo é frequentemente expresso como 'uma interface, funções múltiplas'.

O polimorfismo pode ser estático ou dinâmico. No polimorfismo estático, a resposta a uma função é determinada no momento da compilação. No polimorfismo dinâmico, é decidido em tempo de execução.

C # fornece duas técnicas para implementar polimorfismo estático. Eles são -

  • Sobrecarga de função

  • Sobrecarga do operador

O mecanismo de vinculação de uma função a um objeto durante o tempo de compilação é chamado de vinculação antecipada. Também é chamado de vinculação estática.

Você pode ter várias definições para o mesmo nome de função no mesmo escopo. A definição da função deve diferir uma da outra pelos tipos e / ou número de argumentos na lista de argumentos. Você não pode sobrecarregar as declarações de função que diferem apenas pelo tipo de retorno.

O polimorfismo dinâmico é implementado por classes abstratas e funções virtuais.

Quando uma classe é declarada lacrada, ela não pode ser herdada.

Não! Ele não pode ser criado porque as classes abstratas não podem ser declaradas lacradas.

Quando você tem uma função definida em uma classe que deseja implementar em uma (s) classe (s) herdada (s), você usa funções virtuais. As funções virtuais podem ser implementadas de forma diferente em diferentes classes herdadas e a chamada para essas funções será decidida em tempo de execução.

Você pode redefinir ou sobrecarregar a maioria dos operadores integrados disponíveis em C #. Assim, um programador também pode usar operadores com tipos definidos pelo usuário.

Operadores sobrecarregados são funções com nomes especiais - o operador de palavra-chave seguido pelo símbolo do operador que está sendo definido. Semelhante a qualquer outra função, um operador sobrecarregado tem um tipo de retorno e uma lista de parâmetros.

n interface é definida como um contrato sintático que todas as classes que herdam a interface devem seguir. A interface define a parte 'o quê' do contrato sintático e as classes derivadas definem a parte 'como' do contrato sintático.

As interfaces definem propriedades, métodos e eventos, que são os membros da interface. As interfaces contêm apenas a declaração dos membros. É responsabilidade da classe derivada definir os membros. Freqüentemente, ajuda a fornecer uma estrutura padrão que as classes derivadas seguiriam.

As diretivas do pré-processador fornecem instruções ao compilador para pré-processar as informações antes do início da compilação real.

Todas as diretivas de pré-processador começam com # e apenas os caracteres de espaço em branco podem aparecer antes de uma diretiva de pré-processador em uma linha. As diretivas do pré-processador não são instruções, portanto, não terminam com um ponto e vírgula (;).

Você pode usar a diretiva #if para criar uma diretiva condicional. As diretivas condicionais são úteis para testar um símbolo ou símbolos para verificar se sua avaliação é verdadeira. Se eles forem avaliados como verdadeiros, o compilador avalia todo o código entre o #if e a próxima diretiva.

As exceções C # são representadas por classes. As classes de exceção em C # são derivadas principalmente direta ou indiretamente da classe System.Exception. Algumas das classes de exceção derivadas da classe System.Exception são as classes System.ApplicationException e System.SystemException.

A classe System.ApplicationException oferece suporte a exceções geradas por programas de aplicativos. Portanto, as exceções definidas pelos programadores devem derivar dessa classe.

A classe System.SystemException é a classe base para todas as exceções de sistema predefinidas.