2

I am using ASP.Net Web API 2 and want to create some complex input parameter classes.

I have classes in my library as

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

Now I only need Parent class properties in my child class and I am doing so

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

When I create object of Child class, I want only two properties, which are

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

I don't want GrandParentName property with objChild. Is there any way to skip grand parent classes in inheritance structure as I want to pass this class as API action parameter.

I am feeling lack of multiple inheritance in C# here.

Lali
  • 2,816
  • 4
  • 30
  • 47
  • 4
    You could take a look at composition over inheritence https://en.wikipedia.org/wiki/Composition_over_inheritance – Misters Aug 31 '15 at 14:07
  • 3
    I would ask myself if a Child **has** a Parent or **is** a Parent. – Micke Aug 31 '15 at 14:07
  • 1
    possible duplicate of [How to hide an inherited property in a class without modifying the inherited class (base class)?](http://stackoverflow.com/questions/1875401/how-to-hide-an-inherited-property-in-a-class-without-modifying-the-inherited-cla) – Broots Waymb Aug 31 '15 at 14:07
  • 2
    I would recommend that you explain the actual domain beyond the sample names, this is a design issue more than a language issue and by calling them child, parent and grand parent you are forcing yourself to think that that is the relationship between this objects but the truth is that your current problem suggests they might not be "blood related" after all. – Ernesto Aug 31 '15 at 14:15
  • @Ernesto, I need different combination of classes to pass them to api parameter. I have 'grandparent' and 'Parent' and now I need Parent class properties only, I don't want to create another Parent class, or copy all the properties in Child class. In my project, there are too many actions in controller and each action need a different set of parameters. I am trying to solve this by reuseability of parameters using inheritance. – Lali Aug 31 '15 at 14:24
  • Make private property in grandparent? – M.kazem Akhgary Aug 31 '15 at 14:58
  • @M.kazemAkhgary if it is private then Parent class will not access it. – Lali Aug 31 '15 at 15:06
  • oh .i understand now. so you want to some how chain inheritance. parent only access grandparent properties and child only access parent properties. ill look in to it :P – M.kazem Akhgary Aug 31 '15 at 15:13

2 Answers2

2

I may be misunderstanding something but I think you are going too far with inheritance. You might look to the composite pattern.

I think you are confused between the role of each object compared to each others and inheritance. I am not sure you need all these classes. Here is what I would do :

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

And once you have this, you can achieved what you want :

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

I hope I didn't miss any crucial point :D.

fharreau
  • 2,105
  • 1
  • 23
  • 46
  • In web api, when we pass object of a class, we are exposing all the properties (actually). And if I want to pass 'child' object, I don't want to expose grandparent properties. expose: Using swagger to get all the details of controller api. – Lali Aug 31 '15 at 14:32
  • I am not familiar to WebAPI, but when you pass an object, you are also exposing its private properties ? If you set the Parent property to private and if you are manipulating only IPerson, it won't do the job ? – fharreau Aug 31 '15 at 14:36
  • I just edited my answer with the application of the last comment. – fharreau Aug 31 '15 at 14:40
  • If Person is private then you can't do as --'var parent = new Person { Parent = grandParent };' – Lali Aug 31 '15 at 15:02
  • Yes you can but you need to add a constructor with an optional IPerson parameter that will fill our Parent property. I will edit my answer with that ! – fharreau Aug 31 '15 at 15:21
  • How can I get benefit of that property which I can fill using constructor but can't use... – Lali Aug 31 '15 at 15:26
  • You can use it within the scope of your class, but you can't let other object use it. Set it to internal instead of private so you could use it within the scope of your project but not by another library. You could also imagine another implementation based on my design : Just a ParentName property set during the constructor for example. I just wanted to point out that you may be using inheritance where composition should be enough. – fharreau Aug 31 '15 at 15:32
  • Inheritance is used to add some feature to an object and to share the same base of code. A child is not a parent with new features, it's just a parent with no child yet. A parent is also the child of his own parent. It's a question about roles and not about inheritance. And the pattern to solve that problematic is [Composite](https://en.wikipedia.org/wiki/Composite_pattern). But I may be missing something and this is why you used inheritance ? – fharreau Aug 31 '15 at 15:37
0

As it seems, you may need to change your GrandParent from class to interface, then that might work, if you need those properties just make extra class that implements interface. Remember that you can implement as many interfaces as you need on a single class. And still they have common name for use in Lists and stuff.

fharreau gave example.

If you want better example you should make some data diagram concerning data in question.

Darko
  • 67
  • 5
  • Your concept about interface is good, but It is not usable here. When you implement an interface, you need to implement all the properties. So if I need to implement all the properties once again in my class, then why I need interface? – Lali Aug 31 '15 at 15:05
  • Using interfaces you can split your properties into small groups(2-3 pros per interface) and just add them to classes, even without many parent classes. All depends on type of properties in your existing classes(variables or methods). – Darko Aug 31 '15 at 15:14