Esta es probablemente una pregunta novata, pero Google sorprendentemente no proporcionó una respuesta.
Tengo este método bastante artificial
T HowToCast<T>(T t)
{
if (typeof(T) == typeof(string))
{
T newT1 = "some text";
T newT2 = (string)t;
}
return t;
}
Viniendo de un fondo de C ++, esperaba que esto funcionara. Sin embargo, no se puede compilar con "No se puede convertir implícitamente el tipo 'T' a cadena" y "No se puede convertir el tipo 'T' a cadena" para las dos asignaciones anteriores.
Estoy haciendo algo conceptualmente incorrecto o simplemente tengo la sintaxis incorrecta. Por favor, ayúdame a resolver esto.
¡Gracias!
typeof(T) == typeof(string)
se resuelve en tiempo de ejecución, no en tiempo de compilación. Por lo tanto, la siguiente línea en el bloque no es válida.Respuestas:
A pesar de que hay dentro de un
if
bloque, el compilador no sabe queT
esstring
.Por lo tanto, no te permite lanzar. (Por la misma razón que no se puede echar
DateTime
astring
)Debe lanzar a
object
, (a lo que cualquieraT
puede lanzar), y de allí astring
(ya queobject
puede lanzar astring
).Por ejemplo:
fuente
T
:var isBlank = (userDefinedValue is string) && String.IsNullOrWhiteSpace(userDefinedValue as string);
Ambas líneas tienen el mismo problema.
El compilador no sabe que T es una cadena y, por lo tanto, no tiene forma de saber cómo asignar eso. Pero como lo has verificado, puedes forzarlo con
no necesita emitir la t ya que ya es una cadena, también necesita agregar la restricción
fuente
Sé un código similar al OP publicado en esta pregunta de analizadores genéricos. Desde una perspectiva de rendimiento, debe usar
Unsafe.As<TFrom, TResult>(ref TFrom source)
, que se puede encontrar en el paquete System.Runtime.CompilerServices.Unsafe NuGet. Evita el boxeo para los tipos de valor en estos escenarios. También creo que esoUnsafe.As
produce menos código de máquina producido por el JIT que lanzar dos veces (usando(TResult) (object) actualString
), pero no lo he comprobado.Unsafe.As
será reemplazado por el JIT con instrucciones de código de máquina eficientes, como puede ver en el repositorio oficial de CoreFX:fuente
Si está buscando tipos explícitos, ¿por qué declara esas variables como
T
's?fuente
T
.object
valores, con tipos derivados que almacenanstring
valores. Supongamos que estos campos también tienen un valor "DefaultIfNotProvided", por lo que debe verificar si el valor proporcionado por el usuario (que podría ser un objeto o una cadena o incluso una primitiva numérica) es equivalente adefault(T)
. La cadena se puede tratar como un caso especial donde una cadena vacía / espacio en blanco se trata de la misma manera que la predeterminada (T), por lo que es posible que desee verificar siT userValue; var isBlank = (userValue is string) && String.IsNullOrWhitespace(userValue as string);
.También recibirá este error si tiene una declaración genérica tanto para su clase como para su método. Por ejemplo, el código que se muestra a continuación da este error de compilación.
Este código se compila (nota T eliminada de la declaración del método):
fuente
Cambia esta línea:
Para esta línea:
fuente