public static class ComponentExtensions {
private static readonly Dictionary<string, Dictionary<Type, MethodInfo>> overrides = new Dictionary<string, Dictionary<Type, MethodInfo>>();
private static bool HasOverride(object targetObj, [CallerMemberName] string callerName = null) {
if (!vtable.ContainsKey(callerName)) return false;
var overridesForMember = overrides[callerName];
var targetType = targetObj.GetType();
return overridesForMember.ContainsKey(targetType);
}
private static T InvokeOverride<T>(object targetObj, object[] parameters, [CallerMemberName] string callerName = null) {
var overridesForMember = overrides[callerName];
var targetType = targetObj.GetType();
return (T) overridesForMember[targetType].Invoke(targetObj, parameters);
}
private static void InvokeOverride(object targetObj, object[] parameters, [CallerMemberName] string callerName = null) {
var overridesForMember = overrides[callerName];
var targetType = targetObj.GetType();
overridesForMember[targetType].Invoke(targetObj, parameters);
}
// ITangibleEntity
public static Vector3 GetPosition(this ITangibleEntity @this) {
if (HasOverride(@this)) {
return InvokeOverride<Vector3>(@this, new object[] { });
}
return GetAdjunctField(@this, "ITangibleEntity.Position", () => Vector3.Zero);
}
public static void SetPosition(this ITangibleEntity @this, Vector3 newPosition) {
if (HasOverride(@this)) {
InvokeOverride(@this, new object[] { newPosition });
return;
}
SetAdjunctField(@this, "ITangibleEntity.Position", newPosition);
}
public static Vector3 GetVelocity(this ITangibleEntity @this) {
if (HasOverride(@this)) {
return InvokeOverride<Vector3>(@this, new object[] { });
}
return GetAdjunctField(@this, "ITangibleEntity.Velocity", () => Vector3.Zero);
}
public static void SetVelocity(this ITangibleEntity @this, Vector3 newVelocity) {
if (HasOverride(@this)) {
InvokeOverride(@this, new object[] { newVelocity });
return;
}
SetAdjunctField(@this, "ITangibleEntity.Velocity", newVelocity);
}
}
Code snippet taken from "Simulating Multiple Inheritance In C#".