1
votes

Consider the following code:

namespace TestNameSpace {
  public interface IFinder
  {
    IEnumerable<T> GetData<T>(DataStore dataStore);
  }

  public class EmployeeFinder : IFinder {
    public IEnumerable<Employee> GetData<Employee>(DataStore dataStore) {
        return dataStore.Employees; //*****This causes an error*****
    }
  }

  public class DataStore {
    public IEnumerable<Employee> Employees { get; set;}
  }

  public class Employee {

  }
}

The line where I return dataStore.Employees causes a compilation error.

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<TestNameSpace.Employee>' to 'System.Collections.Generic.IEnumerable<Employee>'. An explicit conversion exists (are you missing a cast?)

Why is an implicit conversion required when they are the same type? Why is one namespaced while the other isn't?

Thanks!

2
You have two different types of the same name (Employee) in different namespaces. Look through your codebase for missing namespace declarations or accidentally redefined classes. - Asad Saeeduddin

2 Answers

3
votes

You have used Employee as name for method generic parameter, so you have two different meaning for Employee in your code.

namespace TestNameSpace {
  public interface IFinder
  {
    IEnumerable<T> GetData<T>(DataStore dataStore);
  }

  public class EmployeeFinder : IFinder {
    public IEnumerable<EmployeeGenericParameter> GetData<EmployeeGenericParameter>(DataStore dataStore) {
        return dataStore.Employees;
    }
  }

  public class DataStore {
    public IEnumerable<EmployeeClass> Employees { get; set;}
  }

  public class EmployeeClass {

  }
}

And IEnumerable<EmployeeClass> can not be converted to IEnumerable<EmployeeGenericParameter> as EmployeeGenericParameter can be int or whatever else.

1
votes

You have created two distinct definitions of the type Employee. One as a plain class and the other as the generic parameter to your GetData method.

This is easily fixed. Just move the generic parameter from the GetData method to the IFinder interface itself. Here's how you should have defined your interface:

public interface IFinder<T>
{
    IEnumerable<T> GetData(DataStore dataStore);
}

Now EmployeeFinder works if it's implemented like this:

public class EmployeeFinder : IFinder<Employee>
{
    public IEnumerable<Employee> GetData(DataStore dataStore)
    {
        return dataStore.Employees;
    }
}