Home > Net >  Trying to refactor this to LinQ but getting a invalid cast
Trying to refactor this to LinQ but getting a invalid cast

Time:07-14

So I am wanting to refactor this to LinQ, and not having any luck with it and I am out of search options to guide me in the right direction.

Can someone explain this to me please, as the commented code works and the LinQ well I know I am doing it wrong. Just can't find any information to guide me along.

    public static T Get<T>()
    {
        Type type = typeof(T);

        if (IsRegistered(type))
        {
            //foreach(var service in _services)
            //{
            //    var test = service.InstanceClass;

            //    if(test.GetType().Equals(type))
            //    {
            //        return (T)test;
            //    }
            //}

            return (T) _services.Select(x => x.InstanceClass.GetType() == type);
        }

        return default;
    }

CodePudding user response:

First of all, you want to return T, not bool that's why the final Select is incorrect:

// Returns `bool`: if "x.InstanceClass" is of type "type"
Select(x => x.InstanceClass.GetType() == type)

Now let's state the problem:

  1. From _services we want to return first service.InstanceClass which is of type type
  2. If there are no such items, return default

We can do it like this:

return _services
  .Select(item => item.InstanceClass) 
  .OfType<T>()
  .FirstOrDefault(item => item.GetType() == type);

A brief explanation on what's going on:

  • We should return some item.InstanceClass from _services so put Select.
  • We are interesting in InstanceClass which can be treated as in instance of type T - that's a purpose of OfType<T>().
  • Finally, we want InstanceClass to be exaclty of type T (and not say, of a derived type) and we put FirstOrDefault with condition.

The method can look like this:

public static T Get<T>() {
  // Let's check first for special and edge cases
  if (!IsRegistered(typeof(T)))
    return default;

  return _services
   .Select(item => item.InstanceClass) 
   .OfType<T>()
   .FirstOrDefault(item => item.GetType() == typeof(T));
}  

CodePudding user response:

Select returns an IEnumerable<bool> and you're casting it to T, so make sure you using Where and do a FirstOrDefault() to get only out value.

Try this:

return (T)_services.Where(x => x.InstanceClass.GetType() == type).FirstOrDefault();
  • Related