【问题标题】:Inheritance, how to inherit parent class without grandparent继承,如何在没有祖父母的情况下继承父类
【发布时间】:2023-08-06 09:54:01
【问题描述】:

我正在使用 ASP.Net Web API 2 并想创建一些复杂的输入参数类。

我的图书馆中有课程

public class GrandParent
{
    public int Id {get;set;}
    public string GrandParentName {get;set;}
}
public class Parent : GrandParent
{
    public string ParentName {get;set;}
}

现在我只需要子类中的父类属性,我正在这样做

public class Child : Parent
{
     public string ChildName {get;set;}
}

当我创建 Child 类的对象时,我只想要两个属性,它们是

Child objChild = new Child();
objChild.ParentName;
objChild.ChildName;

我不想要 objChild 的 GrandParentName 属性。有什么办法可以跳过继承结构中的祖父类,因为我想将这个类作为 API 操作参数传递。

我觉得这里的 C# 缺少多重继承。

【问题讨论】:

  • 你可以看看组合而不是继承en.wikipedia.org/wiki/Composition_over_inheritance
  • 我会问自己,孩子父母还是父母。
  • 我建议您解释示例名称之外的实际域,这是一个设计问题,而不是语言问题,通过称它们为孩子、父母和祖父母,您强迫自己认为是这些对象之间的关系,但事实是您当前的问题表明它们可能根本不是“血缘关系”。
  • @Ernesto,我需要不同的类组合将它们传递给 api 参数。我有“祖父母”和“父母”,现在我只需要父类属性,我不想创建另一个父类,或复制子类中的所有属性。在我的项目中,控制器中的动作太多,每个动作都需要一组不同的参数。我试图通过使用继承来重用参数来解决这个问题。

标签: c# asp.net asp.net-web-api


【解决方案1】:

我可能误解了一些东西,但我认为你在继承方面走得太远了。你可以看看composite pattern

我认为您对每个对象的作用与继承之间的比较感到困惑。我不确定您是否需要所有这些课程。这是我会做的:

interface IPerson
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string ParentName { get; }
}

class Person : IPerson
{
    public int Id { get; set; }
    public string Name { get; set; }

    protected IPerson Parent { get; set; }

    public string ParentName { get { return this.Parent != null ? this.Parent.Name : String.empty; } }

    public Person(IPerson parent = null)
    {
        this.Parent = parent;
    }
}

一旦你有了这个,你就可以实现你想要的:

var grandParent = new Person();
var parent = new Person(grandParent);
var child = new Person(parent);

我希望我没有错过任何关键点:D。

【讨论】:

  • 在 web api 中,当我们传递一个类的对象时,我们暴露了所有的属性(实际上)。如果我想传递“子”对象,我不想公开祖父母属性。暴露:使用 swagger 获取控制器 api 的所有细节。
  • 我对WebAPI不熟悉,但是当你传递一个对象时,你也暴露了它的私有属性?如果您将 Parent 属性设置为私有,并且您只操作 IPerson,它不会完成这项工作?
  • 我刚刚使用最后一条评论编辑了我的答案。
  • 如果 Person 是私有的,那么你不能这样做 --'var parent = new Person { Parent = grandParent };'
  • 是的,您可以,但您需要添加一个带有可选 IPerson 参数的构造函数,该参数将填充我们的 Parent 属性。我将用它来编辑我的答案!
【解决方案2】:

看起来,您可能需要将 GrandParent 从类更改为接口,那么这可能会起作用,如果您需要这些属性,只需创建实现接口的额外类。请记住,您可以在单个类上实现任意数量的接口。而且它们仍然有用于列表和其他东西的通用名称。

fharreau 举了一个例子。

如果你想要更好的例子,你应该制作一些关于相关数据的数据图。

【讨论】:

  • 你对接口的概念很好,但在这里不可用。当你实现一个接口时,你需要实现所有的属性。因此,如果我需要在我的类中再次实现所有属性,那我为什么需要接口?
  • 使用接口,您可以将属性分成小组(每个接口 2-3 个专业人员),然后将它们添加到类中,即使没有很多父类。一切都取决于现有类(变量或方法)中的属性类型。
最近更新 更多