I'm working with some code which uses custom attributes for validation. I am trying to overwrite a validated property from the base class in a child class so it uses the same name for binding purposes in our generic controls, but doesn't have the validation attribute.
public interface IBaseClass
{
[TestAttribute]
string Id { get; set; }
}
public interface IChildClass : IBaseClass
{
new string Id { get; set; }
}
public class BaseClass : IBaseClass
{
public string Id { get; set; }
}
public class ChildClass : BaseClass, IChildClass
{
public new string Id { get; set; }
}
My problem is that when our validation framework uses reflection to get the value, it is returning the child value instead of the base value.
For example,
- BaseClass.Id = null
- ChildClass.Id = "B"
Using the PropertyInfo for BaseClass.Id, I receive the value from ChildClass.Id.
Is it possible to use reflection to get BaseClass.Id rather than ChildClass.Id when looking at an object of type ChildClass?
Here's some sample code you can paste into a command line app to see what I am trying to do. I added comments with what I get vs what is Expected.
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting");
ChildClass c = new ChildClass();
c.Id = "B";
foreach (Type interfaceType in GetInterfaces<IChildClass>())
{
foreach (PropertyInfo p in interfaceType.GetProperties())
{
Attribute[] attribs = Attribute.GetCustomAttributes(p, typeof(TestAttribute));
foreach (TestAttribute v in attribs)
{
if (v != null)
{
object val = p.GetValue(c, new object[0]);
// Put breakpoint here
v.Validate(val);
// p.ReflectedType is IBaseClass, so I would expect
// val to be BaseClass.Id (null), however it is instead
// returning me ChildClass.Id ("B")
// Can I use reflection to get BaseClass.Id here,
// without hardcoding any types?
}
}
}
}
Console.ReadLine();
}
private static IList<Type> GetInterfaces<B>()
{
List<Type> interfaces = new List<Type>();
interfaces.Add(typeof(B));
Type[] values = typeof(B).GetInterfaces();
foreach (Type t in values)
{
interfaces.Add(t);
}
return interfaces;
}
}
public interface IBaseClass
{
[TestAttribute]
string Id { get; set; }
}
// for sample purposes, removing inheritance from IBaseClass here
// gets me the desired result, however this is not an option in
// the application I am working on. This base interface must remain on the
// child interface
public interface IChildClass : IBaseClass
{
new string Id { get; set; }
}
public class BaseClass : IBaseClass
{
public string Id { get; set; }
}
public class ChildClass : BaseClass, IChildClass
{
public new string Id { get; set; }
}
public class TestAttribute : Attribute
{
public TestAttribute() { }
public void Validate(object value)
{
if (value == null)
return;
}
}
Note : Question has gone through a couple of iterations as I've tried to sort through the code framework I'm working on, and reproduce a simple example of what I am trying to do. I think I finally have a good working code sample showing what I get vs what I want.