Reputation: 3001
I have two independent classes of a library which doesn't have the same base class, neither I can change the implementation of this classes.
Imagine the classes look like this:
public class A {
public int X { get; } = 1;
}
public class B {
public int X { get; } = 2;
}
Now I want to create a generic class, which is either depending on A
or on B
and access the value of X
in there.
So i did:
public class GenericClass<T>
/*where T : ?*/
{
void Foo(T t) {
int x = t.X; // is this possible and how?
}
}
If I would implement A
and B
on myself, I would define an Interface which implements the Property X
, but I can't do this. Is there any other way, without changing class A
and B
, to say that the Generic T
has the Property X
?
Another idea would be to make child classes of A
and B
which then implement the mentioned Interface, but I want to avoid this.
Upvotes: 0
Views: 182
Reputation: 335
Another option is to use dynamic
.
dynamic d;
d = t; // here t can be an instance of A, or or B, or of anything that has X
int x = d.X;
dynamic
essentially implements "duck typing": if a dynamic
object g
has a property X
, then g.X
will retrieve it. This is an alternative to implementing reflection manually.
Upvotes: 2
Reputation: 62472
You can overload Foo
to take either A
or B
:
void Foo(A t)
{
int x = t.X;
}
void Foo(B t)
{
int x = t.X;
}
If you want to do it for every conceivable class that might have an X
property then you'll need a reflection based solution. For example:
void Foo(object obj)
{
var property = obj.GetType().GetProperty("X");
if(property == null) throw new Exception();
int x = (int)property.GetValue(obj);
}
NOTE: I've minimized the error handling here. You'd need to handle the case where the property might not have a getter (rare) or where it doesn't return an int
If the number of classes is manageable then you could create an interface with the property, derive a new class and implement the interface, which won't require a change. For example:
interface IMyStuff
{
int X{get;}
}
class MyA : A, IMyStuff
{
}
class MyB : B, IMyStuff
{
}
Not you can have Foo accept the interface:
void Foo(IMyStuff stuff)
{
int x = stuff.X
}
Upvotes: 5