I have a BaseClass from which I have derived multiple other Classes using Inheritance.
Elsewhere I want to be able to retrieve Properties from anyone of these inherited classes even though the type of Class isn't known until Runtime.
For example lets say I have two classes derived from BaseClass
FirstClass : BaseClass
SecondClass : BaseClass
My BaseClass has a property called ID which is an int (amongst many others)
At runtime my app will receive 'either' a FirstClass object or a SecondClass object, but either way I need to retrieve the ID property.
public int MyMethod(object unknownClass)
{
int myID = unknownClass.ID;
return myID //...does not compile
}
public int MyMethod(object unknownClass)
{
BaseClass tryCasting = (BaseClass)unknownClass;
int myID = tryCasting.ID;
return myID //...does not compile either
}
I'm not sure what else to try.
How can I get a Property which I know exists without knowing the Object type first?
Don't use object and use BaseClass:
public int MyMethod(BaseClass unknownClass)
{
int myID = unknownClass.ID;
return myID;
}
See the answer from Darren Davies for your specific case of ID. The approaches in this answer are useful when the property is defined in the derived classes, not the base class.
Use dynamic instead of object. That will use the runtime to retrieve the actual object type.
public int MyMethod(dynamic unknownClass)
{
int myID = (int)unknownClass.ID;
return myID;
}
Alternatively, you can use Reflection to retrieve the property value:
var myID = (int)unknownClass.GetType().GetProperty("ID").GetValue(unknownClass);
Polymorfism is the answer. You should know that when you create a class derived from another, the derived class acquires inmediately the properties from the base class. Thus, if you don't redefine the method (override), when you call the method MyMethod on a derived class it will
always call the base method. So the next code should work well :
BaseClass {
private : int id ;
public : int getId { return id ; }
} ;
FirstClass : BaseClass { DO NOT OVERRIDE getID ...} ;
int main (void) {
BaseClass base ;
FirstClass first ;
base = first ;
base.getId() ; //Gets the id of first.
}
What does this program? When you assign first to base you upcast first type to BaseClass. Then when you get to the execution of base.getId() the program lookups if
there is a redefinition (overriding) of this method in FirstClass, if there isn't it calls the base method.
Hope that you find this information useful. You should read the first chapters of "Thinking in C++" of Bruce Eckels, it's a good introduction to Object Oriented Programming.
Related
I have two classes with similar fields:
Class Foo {
string name;
int val;
};
Class Bar {
string name;
int val;
};
Is there a way to use Generics to retrieve the field names and values of objects of these classes? Something along the lines of:
string GetName<T> (T obj)
{
//returns T.name
}
I want to make sure there are compile time checks for this, in case the class fields were to change.
Update:
I do not control the definitions of classes Foo and Bar. They will be exposed to me in a library and can change.
I can use something like the following:
Type myType = myObject.GetType();
var value = myType.GetProperty("name").GetValue(myObject, null);
But I don't think this would check at compile time.
If you want compile-time safety, and you can't modify Foo and Bar, the typical way to deal with this is with overloads:
public string GetName(Foo o) { return o.Name; }
public string GetName(Bar o) { return o.Name; }
The compiler will automatically pick the method that matches the type of the parameter, so you just need to call it with
GetName(eitherObject);
...and it's type-safe.
You can't really use generics because Foo and Bar lack a common interface that exposes Name.
You can use Reflection, of course, but that means abandoning compile-time safety.
This seems to be a case where you could use inheritance. If these two classes have similar fields you could make them implement a base class which has all the shared fields. Here is an example:
public class BaseEntity
{
int val;
protected string name;
public string Name
{
get
{
return name; // Only get is exposed to prevent modifications
}
}
}
public class ClassA : BaseEntity
{
// Other fields or methods
}
public class ClassB : BaseEntity
{
// Other fields or methods
}
I was looking at sample code from MSDN just now and came accross:
namespace IListSourceCS
{
public class Employee : BusinessObjectBase
{
private string _id;
private string _name;
private Decimal parkingId;
public Employee() : this(string.Empty, 0) {} // <<--- WHAT IS THIS???
public Employee(string name) : this(name, 0) {}
It calls the other constructor in that class with that signature. Its a way of implementing the constructor in terms of other constructors. base can also be used to call the base class constructor. You have to have a constructor of the signature that matches this for it to work.
this lets you call another constructor of Employee (current) class with (string, int) parameters.
This is a technique to initialize an object known as Constructor Chaining
This sample might help some of the different derivations... The first obviously has two constructor methods when an instance is created... such as
FirstClass oTest1 = new FirstClass();
or
FirstClass oTest1b = new FirstClass(2345);
The SECOND class is derived from FirstClass. notice it too has multiple constructors, but one is of two parameters... The two-parameter signature makes a call to the "this()" constructor (of the second class)... Which in-turn calls the BASE CLASS (FirstClass) constructor with the integer parameter...
So, when creating classes derived from others, you can refer to its OWN class constructor method, OR its base class... Similarly in code if you OVERRIDE a method, you can do something IN ADDITION to the BASE() method...
Yes, more than you may have been interested in, but maybe this clarification can help others too...
public class FirstClass
{
int SomeValue;
public FirstClass()
{ }
public FirstClass( int SomeDefaultValue )
{
SomeValue = SomeDefaultValue;
}
}
public class SecondClass : FirstClass
{
int AnotherValue;
string Test;
public SecondClass() : base( 123 )
{ Test = "testing"; }
public SecondClass( int ParmValue1, int ParmValue2 ) : this()
{
AnotherValue = ParmValue2;
}
}
A constructor is a special method/function that is ran to initialize the object created based on the class. This is where you run initialization things, as setting default values, initializes members in all ways.
"this" is a special word which points so the very own object you're in. See it as the objects refereence within the object itself used to access internal methods and members.
Check out the following links :
C# When To Use “This” Keyword
When do you use the “this” keyword?
stackoverflow. I'm new to C#, but have experience in C++ and I got stuck with one idea realization:
I want to make an object with abstract properties(not C# properties, but variables) as a base class and N derived classes with such inheritance:
ObjWithProps <-- A <-- B <-- N other classes derived one from another
Properties list is static, so it will be initialized once per type, not per object. Each of A and B can add own abstract properties with unique string-represented names. First of all I was thinking of making it with OpenInstanceDelegates, but it turns out, that delegates can't be covariant, am I right ?
public delegate T OpenGetterDlg<T>(ObjWithProps instance);
I can't simply bind function A.GetSomething() to OpenGetterDlg because of different this parameter and covariance doesn't works here.
I could do that instead:
public delegate TPropType OpenGetterDlg<TPropType, TThisType>(TThisTypeinstance);
but it becomes real pain in the ass when dealing with a list of
class CPropWrapper<TPropType, TInstType> where TInstType : ObjWithProps
{
// Property ID here
// Setter Delegate object here
// Getter Delegate object here
}
Too many casts, too many type params, too many templates ... Maybe someone knows how do that task in C# ? The key ideas: static prop list, any derived classes (A, B, C, D) can add their own props to list, encapsulated and minimal type specification.
Thanks in advance!
UPD1:
Pseudocode
class ObjWithProps
{
class CPropertyWrapper
{
public string Name;
public OpenGetterDelegate Getter;
public OpenSetterDelegate Setter;
}
static List<CpropertyWrapper> AbstractProps;
public CProperty GetPropertyByName(string name)
{
// Find property by name and
return PropertyFromType(Getter());
}
}
CProperty is a base wrapper class for types like int, float, myType1, myType2.
class A: ObjWithProps
{
int IQValue;
public int getIQ() { return IQValue; }
public void setIQ(int iq) { IQValue = iq; }
protected override registerProps()
{
// this one should be called only once
registerProperty<int>("IQ", "getIQ", "setIQ");
}
}
class B: A
{
myType1 X;
public myType1 getX() { return X; }
public void setX(myType1 x) { X= x; }
protected override registerProps()
{
base.registerProps();
registerProperty<myType1>("X", "getX", "setX");
}
}
At first look, you want to re-invent dependency properties from WPF. At least, I can't see any conceptual differences.
I have a question related to OOPS concept.
I have a base class
public class BaseClass
{
public int i = 10;
public int x = 30;
public string str = "Hello";
public virtual string Hello()
{
return "Hello of base class called";
}
}
I have a child class
public class ChildClass : BaseClass
{
public int i = 20;
public int z = 90;
public override string Hello()
{
return "Hello of child class called";
}
}
Now i have seen that the below code works fine
BaseClass baseObject = new ChildClass();
and when I type baseObject. then i only see members of BaseClass only.
First question: Can someone advise me on a situation where a developer needs to do this BaseClass baseObject = new ChildClass();?
Second question: If my BaseClass object has a reference to my child class object then why are my child member variables not accessible through this baseObject?
To answer your first question.
Developers do this to provide abstraction over what actual object they are referring to, which provides flexibility and 'loose-coupling' over the code that uses it.
For example (common scenario - which i use a lot), you might have 10 child classes which extend the base class. What if you wanted a method to return each type of child class? Well, without this type of declaration you would need 10 methods. But if you specified the return type of "BaseClass", you could return all the 10 types of child classes from the one method. This technique ties in closely with the user of interfaces.
E.g
public BaseClass GetDynamicChildClass()
{
if (someCondition) return ChildClass();
else if (someOtherCondition) return SomeOtherChildClass();
}
To answer your second question.
You can't see the child properties because you have said "baseObject" is of type "BaseClass" - the compiler has typed the object to this. In order to access the child properties, you need to cast it as the child type:
BaseClass b = new ChildClass();
int x = b.z; // error.
int x = ((ChildClass)b).z; // works - this is a cast, throws exception in bad conversion
ChildClass c = b as ChildClass; // also works, different type of cast, returns null in bad conversion
int x2 = c.z;
This type of concept (polymorphism) is fundamental to Object-Orientated programming. Have a look at this excellent StackOverflow question: Try to describe polymorphism as easy as you can
It explains it in the simplest way possible, without tying it down to any particular programming framework, which in my opinion is the best way to learn OO.
Hope that helps.
When you want to have objects with individual behavior that have a set of common functions. For example you want to put objects of different types into a list.
The underlying type is still ChildClass but you are currently working on a BaseClass type. That is why you only see the members for BaseClass. It is though still possible to convert the BaseClass instance to a ChildClass instance with a cast operation or the 'as' keyword.
When you do
BaseClass baseObject= new ChildClass();
The static declared type of the object is that of "BaseClass".
Hence you can only see the objects of "BaseClass" type.
If you are sure that the object is of ChildClass Type, you can typecast baseObject to "ChildClass" and then use the ChildClass members
((ChildClass) baseObject). - should help intellisense give you the members of the child class.
Using BaseClass baseObject= new ChildClass(); is the base for RunTime polymorphism.
It is very commonly used if you need the overridden child logic to be called but the interface is that of the base class
EDIT : Example of a scenario where you would use it
Class User has derived classes called Employee and 3rdPartyUser
Class User has a virtual method called GetRoleInformation - which is used to obtain Role Info for user from the companies Active directory.
However, for 3rd party user, as the information does not exist in AD, the logic for getting the Role Information involves calling a Web Service to retrieve the data.
In this case, GetRoleInformation is overridden in 3rdPartyUser class
Now, in the program, on the Login Page, once authenticated, i either get back an object of Employee or 3rdPartyUser.
I pass this object to a method with a signature RoleCollection GetRole( User loggedInUser)
Inside this method, without having to determine the type of the user, i just call loggedInUser.GetRoleInformation and depending on whether it is Employee / 3rdPartyUser, the appropriate base / overridden method will be called and Role data will be retrieved from either AD / Web Service.
Long story short :
Advantage of
BaseClass baseObject= new ChildClass();
OVER
ChildClass baseObject= new ChildClass();
is in scenarios when you are not sure of the exact type of child object that is going to be assigned to baseObject variable eg: in this case Employee / 3rdPartyUser
Eg:
BaseClass baseObject= GetLoggedInUser();
where signature of this method is User GetLoggedInUser(string userid)
Otherwise, in an example like yours, where the object is ALWAYS of type "ChildClass", i beleive that there is no advantage to doing it.
The answer of your first questiom :
this type of implementation is common when we are using abstract factory patten for the i wll give u a simple example which is creates a family ford car ..
public class AbstractFactoryExample
{
public AbstractFactoryExample()
{
string type = "";
CarFactory facotry=null;
if (type == "FORD")
{
facotry = new FordCarFactory();
}
ICar MyFamilyCar = facotry.CreateFamilyCar();
ICar MyCityCar = facotry.CreateCityCar();
}
}
public interface ICar
{
}
public abstract class CarFactory
{
public abstract ICar CreateFamilyCar();
public abstract ICar CreateCityCar();
}
public class FordCarFactory : CarFactory
{
public override ICar CreateFamilyCar()
{
return new FordFamilyCar();
}
public override ICar CreateCityCar()
{
return new FordCityCar();
}
}
public class FordFamilyCar : ICar
{
}
public class FordCityCar : ICar
{
}
to your second question :
you are declaring the object as baseclass so it shows only the methods in it only and if you sure about the the generated instance is of type child class
((ChildClass) baseObject)
can solve the problem
please excuse me for my bad english
Here is an example where the only method we care about is in the base class. By using this type of abstraction we can easily add more report types.
public class Report
{
public virtual string ContentType
{
get { return "application/octet-stream"; }
}
public virtual byte[] Build()
{
return new byte[0];
}
public static Report Create(ReportType type)
{
switch (type)
{
case ReportType.Pdf:
return new PdfReport();
case ReportType.Html:
return new HtmlReport();
case ReportType.Doc:
return new DocReport();
case ReportType.Xls:
return new XlsReport();
default:
return new DefaultReport();
}
}
}
Then from the client side we only have to do this:
ReportType type = GetReportTypeFromFormPost();
Report report = Report.Create(type);
// ...
Response.Write(report.Build());
In fact it makes more sense to you, when you use Factory Pattern (http://gsraj.tripod.com/design/creational/factory/factory.html) to instantiate the object. This would abstract out the implementation specific details to different class.
It is quite puzzling to find out that Generics Constraint Can't Be Casted to Its Derived Type.
Let's say I have the following code:
public abstract class BaseClass
{
public int Version
{ get { return 1; } }
public string FixString { get; set; }
public BaseClass()
{
FixString = "hello";
}
public virtual int GetBaseVersion()
{
return Version;
}
}
public class DeriveClass: BaseClass
{
public new int Version
{ get { return 2; } }
}
And guess what, this method will return a compilation error:
public void FreeConversion<T>(T baseClass)
{
if(baseClass.GetType()==typeof(DeriveClass)
var derivedMe = (DeriveClass)baseClass;
}
I would have to cast the baseClass to object first before I can cast it to DerivedClass, i.e.,
public void FreeConversion<T>(T baseClass)
{
if(baseClass.GetType()==typeof(DeriveClass)
var derivedMe = (DeriveClass)((object)baseClass);
}
Seems to me pretty ugly. Why this is so?
First, you shouldn't be casting a base type variable to a derived type. It's not supposed to work, only the other way around.
Second, why it works via object, is because you remove the compile-time type checks. The compiler can check that a BaseType cannot be cast to DerivedType. But when a variable is object, the compiler leaves it assuming you know what you're doing. Even if it will compile, the code will then crash during execution.
The answer is simple: the compiler can't know that T in your FreeConversion method can be converted to DeriveClass.
As you already stated, the cheap trick is to first cast to object, then to the type you want to go. Ugly, but it works.
Apart from that, it may be that you are violating Liskov Substitution principle, nothing that will harm any animals but can drive your design towards unmaintainable code.
Third, a nice trick to let your base class expose the derived type is something like this:
public class Base<T> where T : Base<T> {
T IAmDerived;
}
public class Derived : Base<Derived> { }
First of all, in your generic method the type T could be a vale type or reference type. And the reason why it allows you to do via 'Object' is that, you're simply doing boxing-unboxing which works for any type in system.
Secondly.it will be a terrible idea to convert/cast a baseclass object into a derived class. You're violating the mechanics of OOP.
If you really want to return an object of type derived from the base class, here's one way possible - the solution is pretty much similar to what Frank has offered.
//This is how you create a function in BaseClass that returns the collection
//of DerivedTypes when called from an object of type derivedclass, no magic just Generics.
//**The BaseClass**
public class BaseClass<T>
where T : BaseClass<T>
{
public HashSet<T> GetHashSet()
{
HashSet<T> _hSet = new HashSet<T>();
//do some work
//create a HashSet<T> and return;
return _hSet;
}
}
//**The Derived Class**
public class DerivedClass : BaseClass<DerivedClass>
{
//you have the method inherited.
}