c# - truques - word tecnicas




Recursos ocultos do c#? (20)

Do CLR via C # :

Ao normalizar cadeias de caracteres, é altamente recomendável que você use ToUpperInvariant em vez de ToLowerInvariant porque a Microsoft otimizou o código para executar comparações de maiúsculas .

Lembro-me de uma vez que meu colega de trabalho sempre mudava as strings para maiúsculas antes de comparar. Sempre me perguntei por que ele faz isso porque acho mais "natural" converter em minúscula primeiro. Depois de ler o livro agora eu sei porque.

Isso veio à minha mente depois que eu aprendi o seguinte desta pergunta :

where T : struct

Nós, desenvolvedores C #, todos sabemos o básico do C #. Quero dizer declarações, condicionais, loops, operadores, etc.

Alguns de nós até dominamos as coisas como Generics , tipos anônimos , lambdas , LINQ , ...

Mas quais são os recursos mais ocultos ou truques do C # que mesmo os fãs de C #, viciados, especialistas mal sabem?

Aqui estão os recursos revelados até agora:


Palavras-chave

Atributos

Sintaxe

Características da linguagem

Recursos do Visual Studio

Estrutura

Métodos e Propriedades

  • Método String.IsNullOrEmpty() por KiwiBastard
  • List.ForEach() método por KiwiBastard
  • BeginInvoke() , EndInvoke() métodos por Will Dean
  • Propriedades Nullable<T>.HasValue e Nullable<T>.Value por Rismo
  • Método GetValueOrDefault por John Sheehan

dicas e truques

  • Bom método para manipuladores de eventos por Andreas HR Nilsson
  • Comparações de maiúsculas por John
  • Acesse tipos anônimos sem reflexão por dp
  • Uma maneira rápida de instanciar propriedades de coleção por Will
  • Funções inline anônimas como JavaScript por roosteronacid

De outros


O @ diz ao compilador para ignorar quaisquer caracteres de escape em uma string.

Só queria esclarecer este ... ele não diz para ignorar os caracteres de escape, ele realmente diz ao compilador para interpretar a string como um literal.

Se você tem

string s = @"cat
             dog
             fish"

Na verdade, ele será impresso como (note que ele inclui até o espaço em branco usado para recuo):

cat
             dog
             fish

  1. ?? - operador de coalescência
  2. using ( statement / directive ) - ótima palavra-chave que pode ser usada para mais do que apenas chamar Dispose
  3. readonly - deve ser usado mais
  4. netmodules - muito ruim não há suporte no Visual Studio

" yield " viria a minha mente. Alguns dos atributos como DefaultValueAttribute 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 (contanto que você use o compilador .NET 3.5 e configurá-la para gerar código 2.0) não parece ser muito conhecida bem.

Edit: kokos, obrigado por apontar o ?? operador, isso é realmente muito útil. Desde que é um pouco difícil de google para ele (como é apenas ignorado), aqui está a página de documentação do MSDN para esse operador: ?? ??


Aqui estão alguns recursos interessantes do C #, sob a forma de palavras-chave não documentadas em C #:

__makeref

__reftype

__refvalue

__arglist

Estas são palavras-chave C # não documentadas (até mesmo o Visual Studio as reconhece!) Que foram adicionadas para um boxe / desempacotamento 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 tamanho variável.

Uma coisa sobre a qual as pessoas não sabem muito é System.WeakReference - uma classe muito útil que controla um objeto, mas ainda permite ao coletor de lixo coletá-lo.

O recurso "oculto" mais útil seria a palavra-chave de retorno de rendimento. Não é realmente escondido, mas muitas pessoas não sabem disso. LINQ é construído sobre isso; Ele permite consultas executadas por atraso gerando uma máquina de estado sob o capô. Raymond Chen recentemente postou sobre os detalhes internos e arrojados .



Duas coisas que eu gosto são propriedades automáticas para que você possa reduzir seu código ainda mais:

private string _name;
public string Name
{
    get
    {
        return _name;
    }
    set
    {
        _name = value;
    }
}

torna-se

public string Name { get; set;}

Também inicializadores de objeto:

Employee emp = new Employee();
emp.Name = "John Smith";
emp.StartDate = DateTime.Now();

torna-se

Employee emp = new Employee {Name="John Smith", StartDate=DateTime.Now()}

Este não é C # per se, mas eu não vi ninguém que realmente usa System.IO.Path.Combine() na medida em que deveriam. Na verdade, toda a classe Path é realmente útil, mas ninguém a usa!

Estou disposto a apostar que todo aplicativo de produção tem o seguinte código, mesmo que não deva:

string path = dir + "\\" + fileName;

Eu não sabia a palavra-chave "as" por um bom tempo.

MyClass myObject = (MyClass) obj;

vs

MyClass myObject = obj as MyClass;

O segundo retornará null se obj não for um MyClass, em vez de lançar uma exceção de conversão de classe.


Eu tenho a tendência de descobrir que a maioria dos desenvolvedores de C # não sabe sobre os tipos 'anuláveis'. Basicamente, primitivos que podem ter um valor nulo.

double? num1 = null; 
double num2 = num1 ?? -100;

Defina um double anulável, num1 , para null e defina um double regular, num2 , para num1 ou -100 se num1 for null.

http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx

mais uma coisa sobre o tipo Nullable:

DateTime? tmp = new DateTime();
tmp = null;
return tmp.ToString();

é return String.Empty. Confira this link para mais detalhes


Meu truque favorito é usar o operador coalesce nulo e parênteses para instanciar automaticamente as coleções para mim.

private IList<Foo> _foo;

public IList<Foo> ListOfFoo 
    { get { return _foo ?? (_foo = new List<Foo>()); } }

Tudo mais, mais

1) genéricos implícitos (por que apenas em métodos e não em classes?)

void GenericMethod<T>( T input ) { ... }

//Infer type, so
GenericMethod<int>(23); //You don't need the <>.
GenericMethod(23);      //Is enough.

2) lambdas simples com um parâmetro:

x => x.ToString() //simplify so many calls

3) tipos e inicializadores anônimos:

//Duck-typed: works with any .Add method.
var colours = new Dictionary<string, string> {
    { "red", "#ff0000" },
    { "green", "#00ff00" },
    { "blue", "#0000ff" }
};

int[] arrayOfInt = { 1, 2, 3, 4, 5 };

Outro:

4) Propriedades automáticas podem ter diferentes escopos:

public int MyId { get; private set; }

Obrigado @pzycoman por me lembrar:

5) Pseudônimos de namespace (não é provável que você precise dessa distinção específica):

using web = System.Web.UI.WebControls;
using win = System.Windows.Forms;

web::Control aWebControl = new web::Control();
win::Control aFormControl = new win::Control();

Evite a verificação de manipuladores de eventos nulos

Adicionando um delegado vazio para eventos na declaração, suprimindo a necessidade de sempre verificar o evento para null antes de chamar é incrível. Exemplo:

public delegate void MyClickHandler(object sender, string myValue);
public event MyClickHandler Click = delegate {}; // add empty delegate!

Deixe você fazer isso

public void DoSomething()
{
    Click(this, "foo");
}

Em vez disso

public void DoSomething()
{
    // Unnecessary!
    MyClickHandler click = Click;
    if (click != null) // Unnecessary! 
    {
        click(this, "foo");
    }
}

Por favor, veja também esta discussão relacionada e este post de Eric Lippert sobre este tópico (e possíveis desvantagens).


Uniões (o tipo de memória compartilhada C ++) em C # puro e seguro

Sem recorrer a modos e ponteiros inseguros, você pode fazer com que os alunos compartilhem espaço de memória em uma classe / struct. Dada a seguinte classe:

[StructLayout(LayoutKind.Explicit)]
public class A
{
    [FieldOffset(0)]
    public byte One;

    [FieldOffset(1)]
    public byte Two;

    [FieldOffset(2)]
    public byte Three;

    [FieldOffset(3)]
    public byte Four;

    [FieldOffset(0)]
    public int Int32;
}

Você pode modificar os valores dos campos de byte manipulando o campo Int32 e vice-versa. Por exemplo, este programa:

    static void Main(string[] args)
    {
        A a = new A { Int32 = int.MaxValue };

        Console.WriteLine(a.Int32);
        Console.WriteLine("{0:X} {1:X} {2:X} {3:X}", a.One, a.Two, a.Three, a.Four);

        a.Four = 0;
        a.Three = 0;
        Console.WriteLine(a.Int32);
    }

Produz isto:

2147483647
FF FF FF 7F
65535

Basta adicionar usando System.Runtime.InteropServices;


Aqui está uma útil para expressões regulares e caminhos de arquivo:

"c:\\program files\\oldway"
@"c:\program file\newway"

O @ diz ao compilador para ignorar quaisquer caracteres de escape em uma string.


Este não é tão "oculto" quanto é chamado erroneamente.

Muita atenção é dada aos algoritmos "map", "reduce" e "filter". O que a maioria das pessoas não percebe é que o .NET 3.5 adicionou todos esses três algoritmos, mas deu-lhes muito nomes SQL, baseados no fato de que eles são parte do LINQ.

"map" => Select
Transforma dados de um formulário em outro

"reduce" =>
Agrega os valores agregados em um único resultado

"filter" => Onde os
dados dos filtros são baseados em um critério

A capacidade de usar o LINQ para executar trabalhos em linha em coleções que costumavam executar iterações e condicionais pode ser incrivelmente valiosa. Vale a pena aprender como todos os métodos de extensão do LINQ podem ajudar a tornar seu código muito mais compacto e passível de manutenção.


Se você está tentando usar chaves dentro de uma expressão String.Format ...

int foo = 3;
string bar = "blind mice";
String.Format("{{I am in brackets!}} {0} {1}", foo, bar);
//Outputs "{I am in brackets!} 3 blind mice"

Talvez não seja uma técnica avançada, mas uma que eu vejo o tempo todo que me deixa louco:

if (x == 1)
{
   x = 2;
}
else
{
   x = 3;
}

pode ser condensado para:

x = (x==1) ? 2 : 3;

Mixins Basicamente, se você deseja adicionar um recurso a várias classes, mas não pode usar uma classe base para todas elas, faça com que cada classe implemente uma interface (sem membros). Em seguida, escreva um método de extensão para a interface , ou seja,

public static DeepCopy(this IPrototype p) { ... }

Claro, alguma clareza é sacrificada. Mas funciona!


Se você quiser sair do seu programa sem chamar finalmente algum bloco ou finalizador use FailFast :

Environment.FailFast()






hidden-features