Context
I have an abstract parent class, Register
, and two interfaces which require the implementation of the generic delegates Func<T>
and Action<T>
respectively:
public abstract class Register
{
public int Address { get; protected set; }
public string ID { get; protected set; }
public abstract Type TargetType { get; }
public abstract bool TargetIsArray { get; }
}
public interface IReadableRegister<T>
{
Func<T> GetAccessor { get; }
}
public interface IWritableRegister<T>
{
Action<T> SetAccessor { get; }
}
These are used to define a number of sub-classes, such as:
public class FooRegister<T> : Register, IReadableRegister<T>
{
public override Type TargetType => typeof(T);
public override bool TargetIsArray => TargetType.IsArray;
public Func<T> GetAccessor { get; }
// Further unique members
public FooRegister(int address, object target, PropertyInfo targetProperty)
{
this.Address = address;
this.ID = targetProperty.Name;
this.GetAccessor = (Func<T>)targetProperty.GetMethod.CreateDelegate(typeof(Func<T>),target);
}
}
public class BarRegister<T> : Register, IWritableRegister<T>
{
public override Type TargetType => typeof(T);
public override bool TargetIsArray => TargetType.IsArray;
public Action<T> SetAccessor { get; }
// Further unique members
public BarRegister(int address, object target, PropertyInfo targetProperty)
{
this.Address = address;
this.ID = targetProperty.Name;
this.SetAccessor = (Action<T>)targetProperty.SetMethod.CreateDelegate(typeof(Action<T>),target);
}
}
Usage
Using reflection, I build a List<Register>
which ultimately provides a collection Get/Set delegates for the public properties of a target object (by a number a criteria irrelevant to this question). I wish to be able to index this List<Register>
by ID
(easily done) in order to then invoke the GetAccessor
and/or SetAccessor
as required.
Problem
I have so far failed to handle an element returned from the List<Register>
as the specific generic type it was upon addition, since any cast requires me to use the variable Register.TargetType
and generics must be typed at compile time.
Question(s)
I am aware of possible solutions to the issue such as that detailed here Setting generic type at runtime and also dynamic
usage, however I feel that my approach is fundamentally flawed. How else might this functionality be achieved? Surely generics with polymorphic types are regularly handled?