C#, Access Child Properties from Parent Reference

Accessing child class properties through function in parent class

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.

How to get child property inside parent class?

Use an abstract/virtual property instead of a field:

abstract class ClassA
{
public abstract string MyProperty
{
get;
}

public void DoIt()
{
Console.WriteLine(this.MyProperty);
}
}

class ClassB : ClassA
{
public override string MyProperty
{
get { return "prop_b"; }
}
}

class ClassC : ClassA
{
public override string MyProperty
{
get { return "prop_c"; }
}
}

var instB = new ClassB();
var instC = new ClassC();
instB.DoIt();
instC.DoIt();

See: Inheritance (C# Programming Guide)

See: override (C# Reference)

How can I access a Child class's interface property when that child is stored in a list as its Parent?

Use type casting:

((IFoo)Parents[0]).Bar

But actually it is bad design in your case if you depend on inplementation.

Is it possible to access child class members that are not in parent class from a parent class type reference variable pointing to child class object?

You are right, you cannot write:

employee.AnnualSalary = 1234;

But this is not your case.

You are just using an object initializer to initialize a FullTimeEmployee object(You have access to all public fields/properties).

Basically you are doing the following:

FullTimeEmployee employeeTemp = new FullTimeEmployee();
employeeTemp .AnnualSalary =2000;
Employee employee =employeeTemp;
Update

I thought one can not typecast parent class object to child class
object since a child can do everything that parent can but vice versa
is not true.

Once again you are right.

And once again this is not your case...

The return type of the method might be Employee but the actual object you return might be something else (a derived class).

In this case you can safely cast the object to your derived type.

Check the following example

namespace CastExample
{
class Program
{
static void Main(string[] args)
{
Employee emp = GetEmployee();
FullTimeEmployee full = (FullTimeEmployee)emp;
System.Console.WriteLine(full.AnnualSalary);
PartTimeEmployee part = (PartTimeEmployee)emp;//InvalidCastException
System.Console.ReadLine();
}

static Employee GetEmployee()
{
return new FullTimeEmployee() { Name = "George", AnnualSalary = 1234 };
}
}
public class Employee
{
public string Name;
}
public class FullTimeEmployee : Employee
{
public int AnnualSalary { get; set; }
}
public class PartTimeEmployee : Employee
{
public int HourlyPay { get; set; }
public int HoursWorked { get; set; }
}
}

And he can access private properties too??

Yes,you can access private fields using reflection

Find a private field with Reflection?

How to get the value of private field in C#?

c# use reflection to get a private member variable from a derived class

Check this :
Why can reflection access protected/private member of class in C#?

@Marc Gravell's answer explain why you can do this but pay special attention to @Tamas Czinege's answer (I quote it here again)

Member accessibility is not a security feature. It is there to protect
the programmer against himself or herself. It helps implementing
encapsulation but it is by no means a security feature.

Accessing a parent instance's properties?

You can't.

The two options you list are really the only way to do it.

Remember that any class instance exists at an address in memory. Variables just tell your application where to look in memory for the data. So sure, you can use reflection to find the ImportantInfo property of an instance of Foo, but which instance? Where should it look for it in memory? You have to know where in memory to look.

You know where in memory to look by using a variable. So you need to pass a variable to Bar somehow.

If there was a way to use reflection to find every active instance of a class, you could use that to figure it out in a round-about way, but there is no way to do that.

A small note: when you pass a string to a method, you aren't creating a duplicate. More on that here if you're interested.

Access parent property name from child class

In the constructor the instance if class B be will not be associated with A at all. The assignment to prop1 or prop2 can only happen after the constructor completes.

Without a direct reference in B to A there is no way for B to know what property it is related to. If B has a reference to A, it could check each property of A and see which is equal to it, but this is not a particularly pretty solution.

Another strategy you could use is to do some work in the property of A to mark the instance of B as belonging to A through prop1 or prop2. In the implementation below I use CallerMemberName so as not to pass the name as a string, the compiler will pass it to us when the method is invoked

class A
{
private B _prop1;
public B prop1
{
get => _prop1;
set => SetProp(value, ref _prop1);
}

private B _prop2;
public B prop2
{
get => _prop2;
set => SetProp(value, ref _prop2);
}

private void SetProp(B value, ref B field, [CallerMemberName] string propName = null)
{
if(field != null) field.Association = null;
field = value;
if (field != null) field.Association = propName;
}

}

class B
{
public string Association { get; set; }
}

Accessing child object from parent object in EF Core

Well, I can't see your query but I'd suggest the following.
First, the foreign key should be :

public int EmployeeAreaId {get; set;}

then you have two options to get data from database.
If you are using EF, then:

db.EmployeeArea.Include(e => e.EmployeeName).ToList();

which will return a list of employeeArea including the child list.

Using Linq will be like :

var employeeArea = (from e in db.EmployeeArea
select new EmployeeArea
{
Id = e.Id
// continue populating the model properties
EmployeeNames = db.EmployeeName.Where(e =>
e.EmployeeAreaId == e.Id).ToList(),
}).ToList()

Excuse any typo here. Hope it helps.

Be sure when looping through parents to check if their child list is null.

Including setter property on child class that inherited the property from a read-only interface

You can achieve your goal by explicitly implementing the interface. In this example, my implementation makes use of the existing property (adjusted to type PersonData):

public class Person : IPerson
{//need to implement IPersonData
public PersonData PersonData { get; set; } = new PersonData();
IPersonData IPerson.PersonData => PersonData;
//other stuff
}

The code

Person fred = new Person(); 
fred.PersonData.Name = "Fred";
Console.WriteLine(fred.PersonData.Name);

outputs

Fred

The class now fulfills the contract of IPerson and provides additional functionality not defined in a contract (interface).



Related Topics



Leave a reply



Submit