Isso veio à minha mente depois que aprendi o seguinte com esta pergunta :
where T : struct
Nós, desenvolvedores de C #, todos sabemos o básico de C #. Refiro-me a declarações, condicionais, loops, operadores, etc.
Alguns de nós até dominam coisas como Genéricos , tipos anônimos , lambdas , LINQ , ...
Mas quais são os recursos ou truques mais ocultos do C # que mesmo os fãs, viciados e especialistas em C # mal conhecem?
Aqui estão os recursos revelados até agora:
Palavras-chave
yield
por Michael Stumvar
por Michael Stumusing()
declaração de kokosreadonly
por kokosas
por Mike Stoneas
/is
Por Ed Swangrenas
/is
(melhorado) por Rocketpantsdefault
por deathofratsglobal::
por pzycomanusing()
Blocos por AlexCusevolatile
por Jakub Šturcextern alias
por Jakub Šturc
Atributos
DefaultValueAttribute
por Michael StumObsoleteAttribute
por DannySmurfDebuggerDisplayAttribute
por StuDebuggerBrowsable
eDebuggerStepThrough
por bdukesThreadStaticAttribute
por marxidadFlagsAttribute
por Martin ClarkeConditionalAttribute
por AndrewBurns
Sintaxe
??
(coalesce nulls) operator por kokos- Bandeiras de número por Nick Berardi
where T:new
por Lars Mæhlum- Genéricos implícitos de Keith
- Lambdas de um parâmetro por Keith
- Auto propriedades por Keith
- Alias de namespace de Keith
- Literais de string verbais com @ by Patrick
enum
valores por lfoust- @variablenames por marxidad
event
operadores por marxidad- Formatar colchetes por Portman
- Modificadores de acessibilidade de acessador de propriedade por xanadont
- Operador condicional (ternário) (
?:
) por JasonS checked
eunchecked
operadores por Binoj Antonyimplicit and explicit
operadores de Flory
Características da linguagem
- Tipos anuláveis por Brad Barker
- Tipos anônimos por Keith
__makeref __reftype __refvalue
por Judah Himango- Inicializadores de objeto por lomaxx
- Formate strings de David em Dakota
- Métodos de extensão por marxidad
partial
métodos de Jon Erickson- Diretivas de pré-processador de John Asbeck
DEBUG
diretiva pré-processador de Robert Durgin- Sobrecarga de operador por SefBkn
- Digite dedução por chakrit
- Operadores booleanos levados ao próximo nível por Rob Gough
- Passe a variável do tipo valor como interface sem boxe por Roman Boiko
- Determinar programaticamente o tipo de variável declarada por Roman Boiko
- Construtores estáticos de Chris
- Mapeamento ORM mais fácil nos olhos / condensado usando LINQ da roosteronacid
__arglist
por Zac Bowling
Recursos do Visual Studio
- Selecionar bloco de texto no editor por Himadri
- Snippets por DannySmurf
Estrutura
TransactionScope
por KiwiBastardDependantTransaction
por KiwiBastardNullable<T>
por IainMHMutex
por DiagoSystem.IO.Path
por ageektrappedWeakReference
de Juan Manuel
Métodos e propriedades
String.IsNullOrEmpty()
método por KiwiBastardList.ForEach()
método por KiwiBastardBeginInvoke()
,EndInvoke()
métodos por Will DeanNullable<T>.HasValue
eNullable<T>.Value
propriedades por RismoGetValueOrDefault
método de John Sheehan
dicas e truques
- Bom método para manipuladores de eventos por Andreas HR Nilsson
- Comparações em maiúsculas de John
- Acesse tipos anônimos sem reflexão por dp
- Uma maneira rápida de instanciar preguiçosamente as propriedades de coleção de Will
- Funções inline anônimas do tipo JavaScript por roosteronacid
De outros
- netmodules por kokos
- LINQBridge por Duncan Smart
- Extensões paralelas por Joel Coehoorn
fonte
"a".Equals("A", StringComparison.OrdinalIgnoreCase)
Meu truque favorito é usar o operador de coalescência nula e parênteses para instanciar automaticamente coleções para mim.
fonte
Evite verificar manipuladores de eventos nulos
Adicionar um representante vazio aos eventos na declaração, suprimindo a necessidade de sempre verificar se o evento é nulo antes de chamá-lo de impressionante. Exemplo:
Deixe você fazer isso
Em vez disso
Por favor, veja também esta discussão relacionada e esta postagem de Eric Lippert no blog sobre este tópico (e possíveis desvantagens).
fonte
Tudo o resto, além de
1) genéricos implícitos (por que apenas nos métodos e não nas classes?)
2) lambdas simples com um parâmetro:
3) tipos e inicializadores anônimos:
Outro:
4) As propriedades automáticas podem ter escopos diferentes:
Obrigado @pzycoman por me lembrar:
5) Aliases de namespace (não que você precise dessa distinção específica):
fonte
new web.Control()
também funcionaria neste exemplo. A::
sintaxe obriga a tratar o prefixo como um alias de espaço para nome, para que você possa ter uma classe chamadaweb
e aweb::Control
sintaxe ainda funcione, enquanto aweb.Control
sintaxe não saberá se deve verificar a classe ou o espaço para nome. Por isso, costumo usar sempre::
quando faço alias de namespace.Eu não conhecia a palavra-chave "as" por um bom tempo.
vs
O segundo retornará null se obj não for um MyClass, em vez de lançar uma exceção de conversão de classe.
fonte
Duas coisas de que gosto são as propriedades Automáticas, para que você possa reduzir ainda mais seu código:
torna-se
Também inicializadores de objetos:
torna-se
fonte
[DefaultValue]
é usado para o designer, para que ele saiba se deve mostrar uma propriedade em negrito (ou seja, não padrão).A palavra-chave 'padrão' em tipos genéricos:
resulta em 'null' se T for um tipo de referência e 0 se for um int, false se for um booleano, etc.
fonte
Atributos em geral, mas acima de tudo DebuggerDisplay . Economiza anos.
fonte
Só queria esclarecer este ... ele não diz para ignorar os caracteres de escape, na verdade, diz ao compilador para interpretar a string como um literal.
Se você tem
ele realmente será impresso como (observe que ele inclui o espaço em branco usado para o recuo):
fonte
{{
para{
e}}
para}
torná-lo útilstring.Format()
.Acho que um dos recursos mais subestimados e menos conhecidos do C # (.NET 3.5) são as Árvores de Expressão , especialmente quando combinadas com os Genéricos e Lambdas. Essa é uma abordagem para criação de API que bibliotecas mais recentes, como NInject e Moq, estão usando.
Por exemplo, digamos que eu quero registrar um método com uma API e que a API precise obter o nome do método
Dada esta classe:
Antes, era muito comum ver os desenvolvedores fazerem isso com strings e tipos (ou qualquer outra coisa amplamente baseada em strings):
Bem, isso é péssimo por causa da falta de digitação forte. E se eu renomear "SomeMethod"? Agora, na versão 3.5, no entanto, posso fazer isso de uma maneira fortemente tipada:
Na qual a classe RegisterMethod usa
Expression<Action<T>>
assim:Esse é um dos grandes motivos pelos quais estou apaixonado por Lambdas e Expression Trees no momento.
fonte
EditValue(someEmployee, e => e.FirstName);
na minha lógica de negócios e gerar automaticamente toda a lógica de encanamento para um ViewModel e View para editar essa propriedade (portanto, um rótulo com o texto "Primeiro nome" e um TextBox com uma ligação que chama o setter da propriedade FirstName quando o usuário edita o nome e atualiza a View usando o getter). Essa parece ser a base para a maioria dos novos DSLs internos em C #." rendimento " viria à minha mente. Alguns dos atributos como [DefaultValue ()] também estão entre os meus favoritos.
A palavra-chave " var " é um pouco mais conhecida, mas você também pode usá-la em aplicativos .NET 2.0 (desde que você use o compilador .NET 3.5 e defina-o para gerar o código 2.0) não parece ser muito conhecido. bem.
Edit: kokos, obrigado por apontar o ?? operador, isso é realmente muito útil. Como é um pouco difícil pesquisar no Google (como ?? é apenas ignorado), aqui está a página de documentação do MSDN para esse operador: ?? Operador (Referência de C #)
fonte
Costumo descobrir que a maioria dos desenvolvedores de C # não conhece os tipos 'anuláveis'. Basicamente, primitivas que podem ter um valor nulo.
Defina um duplo anulável, num1 , como nulo, depois defina um duplo regular, num2 , para num1 ou -100 se num1 for nulo.
http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx
mais uma coisa sobre o tipo Nullable:
é retornar String.Empty. Verifique este link para mais detalhes
fonte
as
operadores nulos ) apenas com genéricos. Nullable <T> por si só é rudimentar e longe de ser estelar, mas o conceito de tipos nulos como parte da linguagem é sensacional.Aqui estão alguns recursos interessantes de C # ocultos, na forma de palavras-chave em C # não documentadas:
Essas são palavras-chave em C # não documentadas (até o Visual Studio as reconhece!) Que foram adicionadas a um boxe / unboxing mais eficiente antes dos genéricos. Eles trabalham em coordenação com a estrutura System.TypedReference.
Há também __arglist, que é usado para listas de parâmetros de comprimento variável.
Uma coisa que as pessoas não sabem muito é o System.WeakReference - uma classe muito útil que monitora um objeto, mas ainda permite que o coletor de lixo o colete.
O recurso "oculto" mais útil seria a palavra-chave return return. Não está realmente escondido, mas muitas pessoas não sabem disso. O LINQ é construído sobre isso; Ele permite consultas executadas com atraso, gerando uma máquina de estado sob o capô. Raymond Chen postou recentemente sobre os detalhes internos e arenosos .
fonte
Uniões (o tipo de memória compartilhada C ++) em C # puro e seguro
Sem recorrer ao modo não seguro e aos ponteiros, você pode fazer com que os membros da classe compartilhem espaço de memória em uma classe / estrutura. Dada a seguinte classe:
Você pode modificar os valores dos campos de bytes manipulando o campo Int32 e vice-versa. Por exemplo, este programa:
Emite isso:
basta adicionar using System.Runtime.InteropServices;
fonte
Usando @ para nomes de variáveis que são palavras-chave.
fonte
Se você quiser sair do seu programa sem chamar nenhum bloco ou finalizador, use o FailFast :
fonte
Retornando tipos anônimos de um método e acessando membros sem reflexão.
fonte
Aqui está um útil para expressões regulares e caminhos de arquivo:
O @ diz ao compilador para ignorar qualquer caractere de escape em uma string.
fonte
Mixins. Basicamente, se você deseja adicionar um recurso a várias classes, mas não pode usar uma classe base para todas elas, peça a cada classe que implemente uma interface (sem membros). Em seguida, escreva um método de extensão para a interface , ou seja,
Claro, alguma clareza é sacrificada. Mas funciona!
fonte
Verdadeiro, falso, FileNotFound ?
fonte
Este não é "escondido" tanto quanto é nomeado incorretamente.
Muita atenção é dada aos algoritmos "mapa", "redução" e "filtro". O que a maioria das pessoas não percebe é que o .NET 3.5 adicionou todos esses três algoritmos, mas deu a eles nomes muito SQL-ish, com base no fato de que eles fazem parte do LINQ.
A capacidade de usar o LINQ para realizar trabalhos em linha em coleções que costumavam fazer iterações e condicionais pode ser incrivelmente valiosa. Vale a pena aprender como todos os métodos de extensão LINQ podem ajudar a tornar seu código muito mais compacto e sustentável.
fonte
para novas linhas independentes do sistema.
fonte
Se você estiver tentando usar colchetes dentro de uma expressão String.Format ...
fonte
[
e]
são colchetes<
e>
são colchetes angulares. Consulte en.wikipedia.org/wiki/Bracket .fonte
@ Ed, eu sou um pouco reticente em postar isso, pois é pouco mais do que nitpicking. No entanto, gostaria de salientar que no seu exemplo de código:
Se você vai usar 'is', por que segui-lo com um elenco seguro usando 'as'? Se você constatou que obj é, de fato, MyClass, um elenco padrão:
... nunca vai falhar.
Da mesma forma, você poderia apenas dizer:
Não sei o suficiente sobre as entranhas do .NET para ter certeza, mas meus instintos me dizem que isso reduziria no máximo dois tipos de operações de conversão para um máximo de um. É pouco provável que quebre o banco de processamento de qualquer maneira; pessoalmente, acho que a última forma parece mais limpa também.
fonte
is
eas
não fará transmissões de usuários. Portanto, o código acima está perguntando aois
operador se obj é derivado de MyClass (ou tem uma conversão definida implícita no sistema). Além disso,is
falhanull
. Ambos os casos extremos podem ser importantes para o seu código. Por exemplo, você pode escrever:if( obj == null || obj is MyClass ) c = (MyClass)obj;
Mas isso é estritamente diferente de:try { c = (MyClass)obj; } catch { }
como o primeiro não realizará nenhuma conversão definida pelo usuário, mas o segundo o fará. Sem anull
verificação, o primeiro também não definirác
quandoobj
estánull
.IEnumerable<int>
paraList<int>
e lançandoobject
(new object()
) paraIEnumerable<int>
, para garantir que não haja erros: elenco direto: 5.43ns, é-> como elenco: 6.75ns, como elenco: 5.69ns. Em seguida, testando lançamentos inválidos: elenco direto: 3125000ns, como elenco: 5.41ns. Conclusão: pare de se preocupar com o fator de 1% e certifique-se de que você use / como quando o elenco for inválido, pois as exceções (também se tratadas) são MUITO lentas em comparação com a transmissão, estamos falando de um fator 578000 mais lento. Lembre-se essa última parte, o resto não importa (.Net FW 4.0, compilação de lançamento)Talvez não seja uma técnica avançada, mas eu vejo o tempo todo que me deixa louco:
pode ser condensado para:
fonte