Qualquer produto ou estrutura evolui. Principalmente, é feito para atender às necessidades de seus usuários, alavancar novos poderes de computação e simplesmente torná-lo melhor. Às vezes, o objetivo principal do design também muda com o produto. A estrutura C # ou .net não é exceção. Como vemos, a atual versão 4 é muito diferente em comparação com a primeira. Mas a coisa vem como uma barricada para essa compatibilidade com a evolução anterior.
Na maioria dos frameworks / produtos, alguns recursos seriam cortados se não houvesse necessidade de oferecer suporte à compatibilidade com versões anteriores. De acordo com você, quais são esses recursos em C # / .net?
Mencione um recurso por resposta.
c#
.net
features
backward-compatibility
Gulshan
fonte
fonte
Respostas:
Métodos anônimos . Acho que todos concordam que a sintaxe do método anônimo escolhida para o C # 2.0 é robusta e desajeitada em comparação com a sintaxe lambda que adicionamos ao C # 3.0. É profundamente lamentável ter duas sintaxes quase idênticas para fazer a mesma coisa.
fonte
Eu me livraria das coleções não genéricas. Eles são uma abominação ... e há muitos casos em que estou usando o linq e tenho que fazer algo como
Toda vez que tenho que fazer isso, uma pequena parte da minha alma morre.
fonte
nulo como um tipo . Por que diabos o "vazio" é um tipo? Não possui instâncias, não possui valores, não é possível usá-lo como argumento de tipo genérico, tipo de parâmetro formal, tipo local, tipo de campo ou tipo de propriedade. Não tem significado como um tipo; pelo contrário, é um fato sobre o efeito que uma chamada de método tem na pilha da máquina virtual. Mas a máquina virtual é exatamente isso: uma máquina virtual. A máquina real colocará o valor retornado em um registro (normalmente EAX em x86) e não afetará a pilha! O vazio como um tipo é apenas uma péssima idéia.
Pior: quando usado em um tipo de ponteiro
void*
, significa algo completamente diferente do que significa quando usado como um tipo de retorno. Agora, significa "um ponteiro para um local de armazenamento de tipo desconhecido", que não tem nada a ver com seu significado como "um método que não retorna nenhum valor".Podemos substituir
void*
como um tipo de ponteiro porIntPtr
. (Evoid**
comIntPtr*
e assim por diante.) Podemos substituir void como um tipo de retorno por "Unit", um tipo que possui um valor único, ou seja, nulo. Uma implementação do CLR poderia então decidir que uma chamada de função do tipo unidade poderia otimizar seu uso de registradores ou pilhas adequadamente, sabendo que o nulo que está sendo "retornado" pode ser ignorado com segurança.Nesse mundo, você não precisa mais se separar
Func<A, R>
eAction<T>
delegar.Action<T>
é justoFunc<T, Unit>
.fonte
Task
é apenas umTask<Unit>
. Reimplementar os bits da biblioteca do async CTP me fez realmente desejo para isso ...A declaração vazia
;
. Propenso a erros, quase sempre um erro de digitação, e não fornece um significado adicional que ainda não foi expresso por{}
.fonte
Covariância insegura em matrizes do tipo de referência . Com a covariância typesafe ativada
IEnumerable<T>
, pelo menos parte da necessidade de covariância de matriz desapareceu. (Se tivéssemos uma interface de lista somente leitura covariante, não precisaríamos dela.)fonte
IList<T>
herdado deIReadableList<out T>
e não genéricoIPemutable
, poderia suportar coisas como classificação, mas as matrizes o suportariam mais facilmente.O operador mais unário . Operador menos útil de todos os tempos. Se não tivéssemos que guardá-lo para compatibilidade com versões anteriores, eu o retiraria em um piscar de olhos. Quem usa essa coisa, alguém?
(Esclarecimento: O operador unário positivo
+x
não é o operador de pré-incremento++x
, nem o operador de pós-incrementox++
e nem o operador de adição bináriax+y
.)fonte
+1 == 1
. É muito perto de um no-op.if(a == +1 || a == -1){...}
.Padrão de literais numéricos para
double
Para a maioria dos aplicativos de negócios ,
decimal
é mais apropriado de qualquer maneira ... ou talvez seja melhor remover a ideia de um padrão e forçar o desenvolvedor a realmente fazer a escolha.(That "remover o padrão" seria apropriado para algumas outras coisas também. Por exemplo, eu desisti de tentar convencer a todos que as classes devem ser selados por padrão, mas eu suspeito que é mais fácil convencer as pessoas que eles deveriam pensar sobre se a nova classe deve ser selada ou não e explicitada.)
fonte
Isso é mais uma diretriz do que um recurso, mas acho que é importante porque já está muito arraigado na mente das pessoas como a melhor solução canônica:
O padrão oficial para implementar
IDisposable
.É complicado e existem maneiras melhores .
fonte
Eu sei que existem grandes diferenças entre as várias classes de timer. Mas não poderíamos nos livrar de um ou dois deles, afinal?
fonte
Métodos e tipos de
Array
eList<T>
que se tornaram obsoletos com o Linq, por exemplo:Array.TrueForAll
pode ser substituído porEnumerable.All
Array.FindAll
pode ser substituído porEnumerable.Where
List<T>.ConvertAll
pode ser substituído porEnumerable.Select
Predicate<T>
pode ser substituído porFunc<T, bool>
Converter<T,R>
pode ser substituído porFunc<T, R>
IComparer<T>
realmente deve ser um delegadoFunc<T, T, int>
fonte
Predicate<T>
porque captura a intenção de como a função é usada e economiza um pouquinho de digitação.Delegados não genéricos Como coleções não genéricas, delegados não genéricos são inúteis agora que temos as séries Func e Action. E eu teria cortado as variantes em três parâmetros. Se você tiver mais de três parâmetros, faça uma estrutura e use-a como parâmetro único. Declarar um representante específico para manipulação de eventos não é muito SECO.
fonte
Serviços da Web asmx
Eu acho que eles são bastante obsoletos com o WCF hoje em dia.
fonte
Winforms
Seria bom não ter que navegar entre duas plataformas de desktop. O WPF é para onde as coisas estão indo, por isso é frustrante ter uma redundância completa no nível da plataforma.
fonte