I have a few classes i can't change. They have one property Prop3
in common:
public class c1
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
public string Prop3 { get; set; }
}
public class c2
{
public string Prop2 { get; set; }
public string Prop3 { get; set; }
}
public class c3
{
public string Prop5 { get; set; }
public string Prop3 { get; set; }
}
Now I want to acces this property without knowing the type. I thought of using a Interface:
public interface ic
{
string Prop3 { get; set; }
}
But this code throws a invalid cast exception:
c1 c1o = new c1() { Prop3 = "test" };
string res = ((ic)c1o).Prop3;
C# doesn't support compile-time duck-typing, so if you can't change your types, no luck on that.
You can access your property using dynamic
, which allows runtime duck-typing (no compile time checking though, and you lose intellisense if you use Visual Studio):
c1 c1o = new c1() { Prop3 = "test" };
string res = ((dynamic)c1o).Prop3;
Or via reflection:
c1 c1o = new c1() { Prop3 = "test" };
string res = (string)c1o.GetType().GetProperty("Prop3").GetValue(c1o);
Since there's no compile-time checking, you'll need to handle exceptions in case you pass an instance with no Prop3
.
Or if the types are not sealed, you can try implementing your own derived types where you can specify an interface:
public interface ic
{
string Prop3 { get; set; }
}
public class c1d : c1, ic {}
public class c2d : c2, ic {}
public class c3d : c3, ic {}
This would require you control the creation of the instances though, instances will need to be of type c1d
, c2d
, c3d
, won't work if you get objects of type c1
, c2
or c3
You can do explicit type conversions as @David pointed out (which is a clever trick), but that means you'll have two instances of your object. For a very simple case like the one presented in the question, it might do... if you need anything more advanced, that might be quite tricky
Use an adapter-like construction to encapsulate the conversion logic. Of course the downside of this is that you have to modify the class when c4
pops up.
public class Adapter {
public Adapter(object c) {
if (!(c is c1 || c is c2 || c is c3))
throw new NotSupportedException();
_c = c;
}
private readonly object _c;
public string Prop3 {
get {
if (_c is c1) return ((c1)_c).Prop3;
if (_c is c2) return ((c2)_c).Prop3;
if (_c is c3) return ((c3)_c).Prop3;
throw new NotSupportedException();
}
}
}
Usage:
var c1o = new c1() { Prop3 = "test" };
var adapter1 = new Adapter(c1);
var res1 = adapter1.Prop3;
var c2o = new c2() { Prop3 = "test" };
var adapter2 = new Adapter(c2);
var res2 = adapter2.Prop3;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With