Reputation: 8054
I have this method, and I'm convinced that it's the source of another issue I'm having. I believe it's because this method returns a type of object
instead of one of the three concrete types it actually returns.
Here's the method:
public object GetData(TableType type)
{
switch (type)
{
case TableType.Person:
return new Domain.PersonList(_personRepository.Get());
case TableType.Event:
return new Domain.EventList(_eventRepository.Get());
case TableType.User:
return new Domain.UserList(_userRepository.Get());
}
return null;
}
How can I modify this method to return a type other than object
?
Upvotes: 1
Views: 322
Reputation: 2404
Here's a whole answer with a general solution for parameterized types for return value.
class Program
{
public enum TableType
{
Person,
Event,
User
}
class Person
{
public string Name { get; set; }
public Person(string name) { this.Name = name; }
}
class Event
{
public int EventType { get; set; }
public Event(int eventType) { this.EventType = eventType; }
}
class User
{
public string UserName { get; set; }
public User(string username) { this.UserName = username; }
}
public static T GetData<T>(TableType tableType)
{
switch (tableType)
{
case TableType.Person:
Person person = new Person("John");
return (T)Convert.ChangeType(person, typeof(T));
case TableType.Event:
Event evt = new Event(2);
return (T)Convert.ChangeType(evt, typeof(T));
case TableType.User:
User user = new User("jjesus");
return (T)Convert.ChangeType(user, typeof(T));
}
return default(T);
}
static void Main(string[] args)
{
Person person = GetData<Person>(TableType.Person);
Console.WriteLine("Person.Name {0}", person.Name);
Console.WriteLine("Hit any key to continue");
Console.ReadKey();
}
}
Upvotes: 0
Reputation: 176
You could use generics to get this done,
public T GetData<T>()
{
if(typeof(T) == typeof(Domain.PersonList))
return new Domain.PersonList(_personRepository.Get());
else if (typeof(T) == typeof(Domain.EventList))
return new Domain.EventList(_eventRepository.Get());
else if (typeof(T) == typeof(Domain.UserList))
return new Domain.UserList(_userRepository.Get());
}
return default(T);
}
Upvotes: 1
Reputation: 2698
Another possibility is to use Interfaces to guarantee that only one of your three types is returned.
public IDomainList GetData(TableType type)
{
switch (type)
{
case TableType.Person:
return new Domain.PersonList(_personRepository.Get());
case TableType.Event:
return new Domain.EventList(_eventRepository.Get());
case TableType.User:
return new Domain.UserList(_userRepository.Get());
}
return null;
}
So long as PersonList
, EventList
, and UserList
all implement the IDomainList interface, then you are guaranteed to return on of those three types. Then in your implementation, you can determine what to do based on the specific type returned.
Upvotes: 1
Reputation: 2105
First, you must identify what is the "lowest common denominator" base class for the three kinds of repositories. If you do not have one, then you should create one. One way to do this would be
public abstract class repositoryBase
{
public virtual IList<repositoryBase> Get() { }
}
Then each of the three classes woudl inherit from repositoryBase:
public personRepository : repositoryBase
{
public override IList<personRepository> Get()
{
// code here to return the list
}
}
Once you have refactored the class hierarchy in this way, then you don't even need the GetData method. Where you were calling GetData, you now just call someRepository.Get();
If you are already inheriting from something else and adding a Get method to the base class is not a good fit, you can do the same thing I describe here using an Interface. Either approach, base class or interface work equally well in this case and both are good OO practice.
Upvotes: 1
Reputation: 2367
You can create three GetData
functions, that will get the type as a parameter and return the correct type.
public List<TableType.Person> GetData(TableType.Person type)
{
return new Domain.PersonList(_personRepository.Get());
}
public List<TableType.Event> GetData(TableType.Event type)
{
return new Domain.EventList(_eventRepository.Get());
}
public List<TableType.User> GetData(TableType.User type)
{
return new Domain.UserList(_userRepository.Get());
}
The runtime will pick the correct overload according to the type of the parameter.
EDIT: I am assuming that the Domain.xxxxList functions return a list of the mentioned type in this example. It is not required, of course.
Upvotes: 0
Reputation: 6999
What you need is generics.
This way the method will return the type according to type
.
This method for example returns TService
type:
private TService GetService<TService>(ServiceInfo serviceInfo)
where TService : class, ICoordinationExecutionService
{
var service = _executionServices.FirstOrDefault(
x => x.ServiceInfo.InstanceInfo.InstanceId == serviceInfo.InstanceInfo.InstanceId
&& serviceInfo.ServiceTypeName.Equals(x.ServiceInfo.ServiceTypeName));
if (service == null)
{
throw new Exception("invalid service ");
}
return _directory.GetService<TService>(service.ServiceInfo);
}
Upvotes: 2