No se puede convertir de ‘System.Collections.IList’ a ‘System.Collections.Generic.IEnumerable‘.
Utilizando C# 10, estoy tratando de convertir un IEnumerable<string>?
a un IEnumerable<t>
:
IEnumerable<string>? inputs = getValues();
if (inputs is null)
return false;
Type type = typeof(List<>).MakeGenericType(typeof(T));
IList? outputs = (IList?)Activator.CreateInstance(type);
TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
if (converter is null || outputs is null || !converter.CanConvertFrom(typeof(String)))
return false;
foreach (String input in inputs) {
if (converter.IsValid(input))
outputs.Add(converter.ConvertFromString(input));
}
var texpression = new TExpression<t>(outputs);
Estoy obteniendo un error en la última línea, incluso si uso outputs.ToList()
:
No se puede convertir de 'System.Collections.IList' a 'System.Collections.Generic.IEnumerable<t>'
El constructor de TExpression
es:
public TExpression(IEnumerable<t> values) {
Values = values;
}
He intentado cambiar los tipos en mi código de conversión, pero siempre termino con un error en algún lugar.
¿Cómo puedo solucionar esto para poder usar el constructor sin cambiarlo?
Actualización
Usando lo siguiente:
IList<t> outputs = (IList<t>)Activator.CreateInstance(type);
...
foreach (string input in inputs) {
if (converter.IsValid(input))
outputs.Add((T)converter.ConvertFromString(input));
}
Recibo la advertencia (estoy usando <nullable>enable</nullable>
):
Convirtiendo un literal nulo o un valor potencialmente nulo a un tipo no anulable.
T
puede ser un tipo nullable (Int32?) o un tipo no nullable (Int32).
Podría cambiar la línea de código a:
T? output = (T?)converter.ConvertFromString(input);
Esto soluciona la advertencia, pero ¿es correcto?
¿Qué pasa si T es un tipo no nullable?
davy.ai
Para corregir el error, debes cambiar el tipo de
outputs
aIList<t>
en lugar deIList
, ya que quieres crear una lista del mismo tipo queT
. También debes cambiar el tipo detexpression
aTExpression<><t>>
, ya queoutputs.ToList()
devuelve unIEnumerable<t>
, no unList<t>
oIList<t>
.El código modificado debería verse así:
Si
T
es un tipo no nulo, no puedes asignarle un valornull
, por lo que no debes usarT?
en el código de conversión. En su lugar, puedes usar la palabra clavedefault
, que devuelve el valor predeterminado para el tipo (0
paraint
,null
parastring
, etc.). Por ejemplo:Este código garantiza que siempre tengas un valor no nulo de tipo
T
, incluso si la cadena de entrada es inválida onull
.