C#如何创建一个可以返回子类或父类的函数

时间:2014-12-19 03:38:24

标签: c#

不确定我是否在标题上说清楚了。我想要的是这个:
有一个父类:

public class parent  
....  

和一个儿童班:

public class child : parent  
....  

现在我需要一个可以返回的方法:

List<(what goes here?)> GetSomeValue(string id, boolean needChild) {  
  ......  
  if (needChild)  
    return BuildChildResult(id);  
  else  
    return BuildParentResult(id);  
}  

这可能吗?
什么应该在括号中?

5 个答案:

答案 0 :(得分:3)

由于列表不是List<T>,因此返回不同类型的Covariant无法正常工作。

您可以通过降低对实现out通用修饰符IEnumerable<T>

的接口级别的响应来实现目标

所以在这个示例代码模型中,它应该可以工作。

private static IEnumerable<Parent> Test(bool flag) // returns a covariant collection
{
    if (flag)
        return new List<Parent>(); 
    else
        return new List<Child>();
} 

详细了解Covariance and Contravariance

答案 1 :(得分:0)

您可以向类添加接口,并让您的方法返回接口而不是具体类型。

但是我会指出,因为这是一个孩子或父母,而没有其他逻辑,我会考虑制作两种避免施法的方法。它似乎可以保存代码以将其包装在单个方法中,但请记住,然后将转换/分支的复杂性推送给调用者。

答案 2 :(得分:0)

这应该这样做

IEnumerable<parent> GetSomeValue(string id, boolean needChild) {  
  ......  
  if (needChild)  
    return BuildChildResult(id);  
  else  
    return BuildParentResult(id);  
}  

答案 3 :(得分:0)

我认为接口是可行的方法。看看这个程序:

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;
    }
}

运行此命令将创建一个名为myChildren的子列表和一个名为myParents的父列表。

接口只需要一个属性bool IsParent属性。通过它,GetSomeValue方法可以构建适当的父或子,然后返回一个枚举列表,然后可以将其转换为适当的类型。

答案 4 :(得分:0)

您可以按如下方式使用Generic

    public static List<T> GetSomeValue<T>(string id)
    {
        return (typeof(T) == typeof(Child)) ? BuildChildResult(id) as List<T> : BuildParentResult(id) as List<T>;
    }

然后您可以将其称为

        var childList = GetSomeValue<Child>("");
        var parentList = GetSomeValue<Parent>("");