Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing child class properties through function in parent class

My CTO (Chief Technical Officer) asked me to come up with a way where he could write one single function in the base class, and have access to the all the properties of the child class. Here is what I came up with -

Base Class

class Assets
{
    public Assets getPropertyVal(Assets asObj)
    {
        PropertyInfo[] propInfos = asObj.GetType().GetProperties();
        string strAttributeValue = "10";
        foreach (PropertyInfo propInfo in propInfos)
        {
            // Getting the value
            var propValue = propInfo.GetValue(asObj, null);

            // Setting the value
            propInfo.SetValue(asObj, Convert.ChangeType(strAttributeValue, propInfo.PropertyType), null);

        }
        return asObj;
    }
}

Child Class

class House : Assets
{
    public int rooms{get; set;}
}

Program.cs file

class Program
{
    static void Main(string[] args)
    {
        House hsObj = new House();
        hsObj.rooms = 5;

        Assets asObj = hsObj.getPropertyVal(hsObj);
        // Returns asObj as JSON
    }
}

Now this works fine, but I was just wondering if there was a better way to do this in C#.

Note that we do not know what properties will be present in the child class, so this will have to be determined at run-time.

UPDATE : Making it clear, I was just wondering if there is a better way to access the child class properties, one without using reflection. The important point to note is that we have no idea what properties a child class may have.

UPDATE #2 : I am working with a product that has many entities. These entities have different properties. I want to be able to access and work with all these properties in one single place. This function is exactly that. It's that one single place from where I can access all the data.

like image 717
Abijeet Patro Avatar asked Jul 30 '13 05:07

Abijeet Patro


People also ask

Can a parent class access child attributes?

Inheritance concept is to inherit properties from one class to another but not vice versa. But since parent class reference variable points to sub class objects. So it is possible to access child class properties by parent class object if only the down casting is allowed or possible....

Can parent class inherit the properties of child class in Java?

In Java inheritance we can access parent class properties via the child class object, as there is a keyword extends for achieving inheritance.

Can a parent reference point to child object?

The parent class can hold reference to both the parent and child objects. If a parent class variable holds reference of the child class, and the value is present in both the classes, in general, the reference belongs to the parent class variable.

How do you access parent objects from children?

You can do: class Parent{ int a = 20; } class Child extends Parent{ public static void main(String[] args){ Child c = new Child(); System. out.


2 Answers

First, your Program.cs doesn't actually "do" what you say you want. It sounds like you want a program so that you can do this:

Asset myAsset = new House();
myAsset.Rooms = 5;

But, why would you even want to do that anyway? If your asset isn't a House, it will throw an exception, so you will need to check that first:

if (myAsset is House)
    myAsset.Rooms = 5;

At that point, you might as well just cast it to a House though. It sounds like you may want to use a PropertyBag or Dictionary instead of inheritance.

I think what you are describing is this. Note that option 1 doesn't really restrict which properties can be used on which classes, so I'm guessing this won't really work for your specific case.

// Option 1, a Property Bag (Note: this replaces the properties on the classes)
class Asset
{
    Dictionary<string, object> myPropertyBag = new Dictionary<string, object>();

    public T GetProperty<T>(string property)
    {
        // This throws if the property doesn't exist
        return (T)myPropertyBag[property];
    }

    public void SetProperty<T>(string property, T value)
    {
        // This adds the property if it doesn't exist
        myPropertyBag[property] = (object)value;
    }
}

// Option 2, use a switch and override this function in derived classes
class Asset
{
    public int SomePropertyOnAsset { get; set; }

    public virtual T GetProperty<T>(string property)
    {
        switch (property)
        {
            case "SomePropertyOnAsset": return this.SomePropertyOnAsset;

            default: throw new ArgumentException("property");
        }
    }

    public virtual void SetProperty<T>(string property, T value)
    {
        switch (property)
        {
            case "SomePropertyOnAsset": this.SomePropertyOnAsset = (int)value;

            default: throw new ArgumentException("property");
        }
    }
}

class House : Asset
{
    public int Rooms { get; set; }

    public virtual T GetProperty<T>(string property)
    {
        switch (property)
        {
            case "Rooms": return this.Rooms;

            default: return base.GetProperty<T>(property);
        }
    }

    public virtual void SetProperty<T>(string property, T value)
    {
        switch (property)
        {
            case "Rooms": this.Rooms = (int)value; 
                break;

            default: base.SetProperty<T>(property, value);
                break;
        }
    }
}

Then, this is how you use them:

// Option 1
Asset asset = new House();
asset.SetProperty("Rooms", 5);
var rooms = asset.GetProperty<int>("Rooms");

// Option 2
Asset asset = new House();
asset.SetProperty("Rooms", 5);
asset.SetProperty("SomePropertyOnAsset", 10);
asset.SetProperty("SomethingElse", 15); // Throws ArgumentException

A 3rd option is to make Asset a DynamicObject. http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx

If you can't or don't want to make a major change to your Asset base class or touch every entity, you will probably need to use reflection.

like image 73
lukegravitt Avatar answered Sep 18 '22 03:09

lukegravitt


Luke Gravitt is probably right. You might just want to cast it to a house.

House myHouse = asObj as House;
if ( myHouse != null )
{
  // do some fun house stuff
}

Yacht myYacht = asObj as Yacht;
if ( myYacht != null )
{
   // put on monocle
}
like image 36
Derek Avatar answered Sep 20 '22 03:09

Derek