es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para corregir el error, debes cambiar el tipo de outputs a IList<t> en lugar de IList, ya que quieres crear una lista del mismo tipo que T. También debes cambiar el tipo de texpression a TExpression<><t>>, ya que outputs.ToList() devuelve un IEnumerable<t>, no un List<t> o IList<t>.

    El código modificado debería verse así:

    IEnumerable<string>? inputs = getValues();
    
    if (inputs is null)
      return false;
    
    Type type = typeof(List<>).MakeGenericType(typeof(T));
    
    IList<t>? outputs = (IList<t>?)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((T)converter.ConvertFromString(input));
    }
    
    var texpression = new TExpression<><t>>(outputs.ToList());
    

    Si T es un tipo no nulo, no puedes asignarle un valor null, por lo que no debes usar T? en el código de conversión. En su lugar, puedes usar la palabra clave default, que devuelve el valor predeterminado para el tipo (0 para int, null para string, etc.). Por ejemplo:

    foreach (string input in inputs) {
      if (converter.IsValid(input)) 
        outputs.Add((T)(converter.ConvertFromString(input) ?? default(T)));
    }
    

    Este código garantiza que siempre tengas un valor no nulo de tipo T, incluso si la cadena de entrada es inválida o null.

Comments are closed.