Esto vino a mi mente después de aprender lo siguiente de esta pregunta :
where T : struct
Nosotros, los desarrolladores de C #, todos conocemos los conceptos básicos de C #. Me refiero a declaraciones, condicionales, bucles, operadores, etc.
Algunos de nosotros incluso dominamos cosas como genéricos , tipos anónimos , lambdas , LINQ , ...
¿Pero cuáles son las características o trucos más ocultos de C # que incluso los fanáticos, adictos y expertos de C # apenas conocen?
Aquí están las características reveladas hasta ahora:
Palabras clave
yield
por Michael Stumvar
por Michael Stumusing()
declaración de kokosreadonly
por kokosas
por Mike Stoneas
/is
por Ed Swangrenas
/is
(mejorado) por Rocketpantsdefault
por deathofratsglobal::
por pzycomanusing()
bloques por AlexCusevolatile
por Jakub Šturcextern alias
por Jakub Šturc
Atributos
DefaultValueAttribute
por Michael StumObsoleteAttribute
por DannySmurfDebuggerDisplayAttribute
por StuDebuggerBrowsable
yDebuggerStepThrough
por bdukesThreadStaticAttribute
por marxidadFlagsAttribute
por Martin ClarkeConditionalAttribute
por AndrewBurns
Sintaxis
??
(fusionar nulos) operador de kokos- Banderines de números de Nick Berardi
where T:new
por Lars Mæhlum- Genéricos implícitos por Keith
- Lambdas de un parámetro de Keith
- Auto propiedades de Keith
- Alias de espacio de nombres de Keith
- Literales de cadena literales con @ by Patrick
enum
valores por lfoust- @variablenames por marxidad
event
operadores por marxidad- Formatear corchetes por Portman
- Modificadores de accesibilidad de acceso de propiedad por xanadont
- Operador condicional (ternario) (
?:
) por JasonS checked
yunchecked
operadores de Binoj Antonyimplicit and explicit
operadores de Flory
Características del lenguaje
- Tipos anulables por Brad Barker
- Tipos anónimos por Keith
__makeref __reftype __refvalue
por Judá Himango- Inicializadores de objetos por lomaxx
- Cadenas de formato de David en Dakota
- Métodos de extensión por marxidad
partial
métodos de Jon Erickson- Directivas de preprocesador de John Asbeck
DEBUG
directiva de preprocesador de Robert Durgin- Operador sobrecargado por SefBkn
- Inferencia de tipo por chakrit
- Operadores booleanos llevados al siguiente nivel por Rob Gough
- Pase la variable de tipo de valor como interfaz sin boxeo por Roman Boiko
- Determine programáticamente el tipo de variable declarada por Roman Boiko
- Constructores estáticos de Chris
- Mapeo de ORM más fácil en los ojos / condensado usando LINQ por roosteronacid
__arglist
por Zac Bowling
Características de Visual Studio
- Seleccionar bloque de texto en el editor por Himadri
- Fragmentos de DannySmurf
Marco de referencia
TransactionScope
por KiwiBastardDependantTransaction
por KiwiBastardNullable<T>
por IainMHMutex
por DiagoSystem.IO.Path
por ageektrappedWeakReference
por juan manuel
Métodos y propiedades
String.IsNullOrEmpty()
método por KiwiBastardList.ForEach()
método por KiwiBastardBeginInvoke()
,EndInvoke()
métodos de Will DeanNullable<T>.HasValue
yNullable<T>.Value
propiedades de RismoGetValueOrDefault
método por John Sheehan
consejos y trucos
- Buen método para controladores de eventos por Andreas HR Nilsson
- Comparaciones en mayúsculas por John
- Acceda a tipos anónimos sin reflexión por dp
- Una forma rápida de instanciar perezosamente las propiedades de colección de Will
- Funciones en línea anónimas similares a JavaScript de roosteronacid
Otro
- netmodules por kokos
- LINQBridge por Duncan Smart
- Extensiones paralelas de Joel Coehoorn
fuente
"a".Equals("A", StringComparison.OrdinalIgnoreCase)
Mi truco favorito es utilizar el operador de fusión nula y los paréntesis para crear instancias automáticas de colecciones para mí.
fuente
Evite buscar controladores de eventos nulos
Agregar un delegado vacío a los eventos en la declaración, eliminando la necesidad de verificar siempre que el evento sea nulo antes de llamarlo, es increíble. Ejemplo:
Dejarte hacer esto
En lugar de esto
Consulte también esta discusión relacionada y esta publicación de blog de Eric Lippert sobre este tema (y posibles desventajas).
fuente
Todo lo demás, más
1) genéricos implícitos (¿por qué solo en métodos y no en clases?)
2) lambdas simples con un parámetro:
3) tipos anónimos e inicializadores:
Otro:
4) Las propiedades automáticas pueden tener diferentes ámbitos:
Gracias @pzycoman por recordarme:
5) Alias de espacio de nombres (no es probable que necesite esta distinción particular):
fuente
new web.Control()
también funcionaría en este ejemplo. La::
sintaxis lo obliga a tratar el prefijo como un alias de espacio de nombres, por lo que podría tener una clase llamadaweb
y laweb::Control
sintaxis aún funcionaría, mientras que laweb.Control
sintaxis no sabría si verificar la clase o el espacio de nombres. Debido a eso, tiendo a usar siempre::
cuando hago alias de espacios de nombres.No conocía la palabra clave "como" durante bastante tiempo.
vs
El segundo devolverá nulo si obj no es MyClass, en lugar de lanzar una excepción de conversión de clase.
fuente
Dos cosas que me gustan son las propiedades automáticas para que pueda colapsar aún más su código:
se convierte
También objetos inicializadores:
se convierte
fuente
[DefaultValue]
se usa para el diseñador para que sepa si se debe mostrar una propiedad en negrita (es decir, no predeterminada).La palabra clave 'predeterminada' en tipos genéricos:
da como resultado un 'nulo' si T es un tipo de referencia y 0 si es un int, falso si es un booleano, etc.
fuente
Atributos en general, pero sobre todo DebuggerDisplay . Te ahorra años.
fuente
Solo quería aclarar esto ... no le dice que ignore los caracteres de escape, en realidad le dice al compilador que interprete la cadena como un literal.
Si usted tiene
en realidad se imprimirá como (tenga en cuenta que incluso incluye el espacio en blanco utilizado para la sangría):
fuente
{{
a{
y}}
para}
que sea útil parastring.Format()
.Creo que una de las características menos apreciadas y menos conocidas de C # (.NET 3.5) son los árboles de expresión , especialmente cuando se combinan con genéricos y lambdas. Este es un enfoque para la creación de API que las bibliotecas más nuevas como NInject y Moq están utilizando.
Por ejemplo, supongamos que quiero registrar un método con una API y que la API necesita obtener el nombre del método
Dada esta clase:
Antes, era muy común ver a los desarrolladores hacer esto con cadenas y tipos (o algo más basado en cadenas):
Bueno, eso apesta por la falta de tipeo fuerte. ¿Qué sucede si cambio el nombre de "SomeMethod"? Ahora, en 3.5, sin embargo, puedo hacer esto de una manera muy tipada:
En el que la clase RegisterMethod usa
Expression<Action<T>>
así:Esta es una gran razón por la que estoy enamorado de Lambdas y Expression Trees en este momento.
fuente
EditValue(someEmployee, e => e.FirstName);
en mi lógica de negocios y hacer que genere automáticamente toda la lógica de plomería para un ViewModel y View para editar esa propiedad (por lo tanto, una etiqueta con el texto "Nombre" y un TextBox con un enlace que llama al configurador de la propiedad FirstName cuando el usuario edita el nombre y actualiza la Vista usando el captador). Esta parece ser la base de la mayoría de las nuevas DSL internas en C #." ceder " vendría a mi mente. Algunos de los atributos como [DefaultValue ()] también se encuentran entre mis favoritos.
La palabra clave " var " es un poco más conocida, pero parece que no se puede conocer muy bien en las aplicaciones .NET 2.0 (siempre que use el compilador .NET 3.5 y lo configure en el código de salida 2.0). bien.
Editar: kokos, gracias por señalar el ?? operador, eso es realmente muy útil. Dado que es un poco difícil de google (ya que ?? simplemente se ignora), aquí está la página de documentación de MSDN para ese operador: ?? Operador (Referencia de C #)
fuente
Tiendo a encontrar que la mayoría de los desarrolladores de C # no saben acerca de los tipos 'anulables'. Básicamente, primitivas que pueden tener un valor nulo.
Establezca un doble anulable, num1 , en nulo, luego establezca un doble regular, num2 , en num1 o -100 si num1 era nulo.
http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx
Una cosa más sobre el tipo Nullable:
es return String.Empty. Mira este enlace para más detalles
fuente
as
operadores nulos ) solo con genéricos. <T> anulable solo es rudimentario y está lejos de ser estelar, pero el concepto de tipos anulables como parte del lenguaje es increíble.Estas son algunas características interesantes ocultas de C #, en forma de palabras clave de C # no documentadas:
Estas son palabras clave de C # no documentadas (¡incluso Visual Studio las reconoce!) Que se agregaron para un boxeo / unboxing más eficiente antes de los genéricos. Trabajan en coordinación con la estructura System.TypedReference.
También hay __arglist, que se usa para listas de parámetros de longitud variable.
Una cosa de la que la gente no sabe mucho es System.WeakReference , una clase muy útil que realiza un seguimiento de un objeto pero que aún permite que el recolector de basura lo recoja.
La característica "oculta" más útil sería la palabra clave de retorno de rendimiento. No está realmente oculto, pero mucha gente no lo sabe. LINQ está construido sobre esto; permite consultas ejecutadas con retraso al generar una máquina de estado bajo el capó. Raymond Chen recientemente publicó sobre los detalles internos y arenosos .
fuente
Uniones (el tipo de memoria compartida de C ++) en C # puro y seguro
Sin recurrir al modo inseguro y los punteros, puede hacer que los miembros de la clase compartan espacio de memoria en una clase / estructura. Dada la siguiente clase:
Puede modificar los valores de los campos de bytes manipulando el campo Int32 y viceversa. Por ejemplo, este programa:
Salidas esto:
simplemente agregue usando System.Runtime.InteropServices;
fuente
Usando @ para nombres de variables que son palabras clave.
fuente
Si desea salir de su programa sin llamar a ningún bloque o finalizador, use FailFast :
fuente
Devolver tipos anónimos de un método y acceder a miembros sin reflexión.
fuente
Aquí hay una útil para expresiones regulares y rutas de archivos:
El @ le dice al compilador que ignore cualquier carácter de escape en una cadena.
fuente
Mixins Básicamente, si desea agregar una función a varias clases, pero no puede usar una clase base para todas ellas, haga que cada clase implemente una interfaz (sin miembros). Luego, escriba un método de extensión para la interfaz , es decir
Por supuesto, se sacrifica algo de claridad. ¡Pero funciona!
fuente
¿Verdadero, falso, FileNotFound ?
fuente
Este no está "oculto" tanto como está mal nombrado.
Se presta mucha atención a los algoritmos "mapa", "reducir" y "filtro". De lo que la mayoría de la gente no se da cuenta es que .NET 3.5 agregó estos tres algoritmos, pero les dio nombres muy SQL, basados en el hecho de que son parte de LINQ.
La capacidad de usar LINQ para realizar trabajos en línea en colecciones que solían tomar iteraciones y condicionales puede ser increíblemente valiosa. Vale la pena aprender cómo todos los métodos de extensión de LINQ pueden ayudar a que su código sea mucho más compacto y fácil de mantener.
fuente
para líneas nuevas independientes del sistema.
fuente
Si está tratando de usar corchetes dentro de una expresión String.Format ...
fuente
[
y]
son corchetes,<
y>
son corchetes angulares. Ver en.wikipedia.org/wiki/Bracket .fuente
@Ed, soy un poco reticente a publicar esto, ya que es poco más que una trampa. Sin embargo, señalaría que en su ejemplo de código:
Si vas a usar 'es', ¿por qué seguir con un molde seguro usando 'como'? Si ha comprobado que obj es de hecho MyClass, un elenco de pantano estándar:
... nunca va a fallar.
Del mismo modo, podrías decir:
No sé lo suficiente sobre las entrañas de .NET para estar seguro, pero mis instintos me dicen que esto reduciría un máximo de dos operaciones de lanzamiento de tipos a un máximo de uno. Es poco probable que rompa el banco de procesamiento de cualquier manera; personalmente, creo que la última forma también se ve más limpia.
fuente
is
yas
no hará lanzamientos de usuarios. Entonces, el código anterior pregunta con elis
operador si obj se deriva de MyClass (o si tiene un reparto definido implícito en el sistema). Además,is
fallanull
. Ambos casos extremos pueden ser importantes para su código. Por ejemplo, es posible que desee escribir:if( obj == null || obj is MyClass ) c = (MyClass)obj;
Pero esto es estrictamente diferente de:try { c = (MyClass)obj; } catch { }
dado que el primero no realizará ninguna conversión definida por el usuario, pero el segundo sí. Sin elnull
cheque, el primero tampoco se establecerác
cuandoobj
seanull
.IEnumerable<int>
aList<int>
, y la fundiciónobject
(new object()
) queIEnumerable<int>
, para asegurarse de que no hay errores: fundición directa: 5.43ns, es-> como elenco: 6.75ns, como reparto: 5.69ns. Luego, prueba de lanzamientos no válidos: lanzamiento directo: 3125000ns, como lanzamiento: 5.41ns. Conclusión: deja de preocuparte por el factor 1% y solo asegúrate de usar is / as cuando el lanzamiento podría no ser válido, porque las excepciones (también si se manejan) son MUY lentas en comparación con el lanzamiento, estamos hablando de un factor 578000 más lento. Recuerde que la última parte, el resto no importa (.Net FW 4.0, versión de lanzamiento)Tal vez no sea una técnica avanzada, pero una que veo todo el tiempo que me vuelve loco:
se puede condensar a:
fuente