Reputation: 2552
Not sure if I made it clear on the title. What I want is this:
There is a parent class:
public class parent
....
And a child class:
public class child : parent
....
Now I need a method that can return either:
List<(what goes here?)> GetSomeValue(string id, boolean needChild) {
......
if (needChild)
return BuildChildResult(id);
else
return BuildParentResult(id);
}
Is this something possible to do?
What should be in the bracket?
Upvotes: 0
Views: 2887
Reputation: 4498
This should do it
IEnumerable<parent> GetSomeValue(string id, boolean needChild) {
......
if (needChild)
return BuildChildResult(id);
else
return BuildParentResult(id);
}
Upvotes: 0
Reputation: 1038
You can use Generic as follows
public static List<T> GetSomeValue<T>(string id)
{
return (typeof(T) == typeof(Child)) ? BuildChildResult(id) as List<T> : BuildParentResult(id) as List<T>;
}
Then you can call it like
var childList = GetSomeValue<Child>("");
var parentList = GetSomeValue<Parent>("");
Upvotes: 0
Reputation: 48696
I think an interface is the way to go. Look at this program:
class Program
{
static void Main(string[] args)
{
bool needChild = true;
IEnumerable<IMyClass> myChildList = GetSomeValue("1", needChild);
List<Child> myChildren = myChildList.Cast<Child>().ToList();
needChild = false;
IEnumerable<IMyClass> myParentList = GetSomeValue("1", needChild);
List<Parent> myParents = myParentList.Cast<Parent>().ToList();
}
private static IEnumerable<IMyClass> GetSomeValue(string id, bool needChild)
{
if (needChild)
{
return BuildChildResult(id);
}
return BuildParentResult(id);
}
private static IEnumerable<IMyClass> BuildChildResult(string id)
{
var list = new List<IMyClass>
{
new Child {ChildName = "Test 1", Id = "1"},
new Child {ChildName = "Test 2", Id = "1"},
new Child {ChildName = "Test 3", Id = "1"},
new Child {ChildName = "Test 4", Id = "2"},
new Child {ChildName = "Test 4", Id = "2"},
new Child {ChildName = "Test 4", Id = "3"}
};
return list.Where(z => z.Id == id).ToList();
}
private static IEnumerable<IMyClass> BuildParentResult(string id)
{
var list = new List<IMyClass>
{
new Parent {ParentName = "Test 1", Id = "1"},
new Parent {ParentName = "Test 2", Id = "1"},
new Parent {ParentName = "Test 3", Id = "1"},
new Parent {ParentName = "Test 4", Id = "2"},
new Parent {ParentName = "Test 4", Id = "2"},
new Parent {ParentName = "Test 4", Id = "3"}
};
return list.Where(z => z.Id == id).ToList();
}
}
public interface IMyClass
{
string Id { get; set; }
bool IsParent { get; set; }
}
public class Parent : IMyClass
{
public string Id { get; set; }
public bool IsParent { get; set; }
public string ParentName { get; set; }
public Parent()
{
IsParent = true;
}
}
public class Child : IMyClass
{
public string Id { get; set; }
public bool IsParent { get; set; }
public string ChildName { get; set; }
public Child()
{
IsParent = false;
}
}
Running this will create a child list called myChildren and a parent list called myParents.
The interface only needs one property, the bool IsParent property. Through that, the GetSomeValue method can build the appropriate parent or child, then return an enumerated list, which can then be cast to the appropriate type.
Upvotes: 0
Reputation: 1977
Returning different types of List<T>
wont work since List is not Covariant
.
You can achieve your goal by lowering your response to the Interface level that implements the out
generic modifier which is the IEnumerable<T>
So in this example code mockup, it should work.
private static IEnumerable<Parent> Test(bool flag) // returns a covariant collection
{
if (flag)
return new List<Parent>();
else
return new List<Child>();
}
Read more about Covariance and Contravariance
Upvotes: 6
Reputation: 39258
You can add an interface to the classes and have your method return an interface instead of a concrete type.
However I would point out that since this is either a child or a parent, and no other logic, I would consider making it two methods to avoid the casting. It may seem like it saves code to wrap it in a single method, but keep on mind that the complexity of casting/branching is then pushed out to the caller.
Upvotes: 0