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

本文关键字:子类 返回 父类 函数 何创建 创建 一个 | 更新日期: 2023-09-27 18:34:43

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

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

这是可以做到的吗?
括号里应该有什么?

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

返回

不同类型的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>();
} 

阅读更多关于协方差和逆变的信息

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

但是我要指出的是,由于这要么是子项,要么是父项,并且没有其他逻辑,因此我会考虑将其设置为两种方法以避免铸造。看起来它似乎保存了代码以将其包装在单个方法中,但请记住,转换/分支的复杂性随后被推送给调用方。

我认为界面是要走的路。看看这个程序:

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 方法可以生成适当的父项或子项,然后返回一个枚举列表,然后可以将其转换为适当的类型。

您可以按如下方式使用 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>("");

应该可以做到

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