Распространенный шаблон в этом случае - иметь неуниверсальный базовый тип общего базового типа.Если ваш метод не включает параметр типа, то все готово.Если это так, вы можете добавить неуниверсальный метод, который выполняет приведение типа, аналогично Object.Equals:
public abstract class ReallyBaseType
{
public abstract void SomeMethod();
public abstract void SomeMethodWithParameter(object o);
}
public abstract class BaseType<TEntity> : ReallyBaseType
where TEntity : BaseType<TEntity>
{
public override void SomeMethodWithParameter(object o)
{
SomeMethodWithParameter((TEntity)o);
}
public abstract void SomeMethodWithParameter(TEntity entity);
}
public class AnyType : BaseType<AnyType>
{
public override void SomeMethod() { }
public override void SomeMethodWithParameter(AnyType entity) { }
}
Затем вы можете просто проверить фактический тип данных:
public void Method<T>(T data)
{
if (data is ReallyBaseType)
{
((ReallyBaseType)(object)data).SomeMethod();
}
}
РЕДАКТИРОВАТЬ: Я думаю, что вы застряли с помощью отражения, тогда.Если вы хотите иметь возможность писать код для конкретного типа, вы можете создать универсальный метод и вызывать его, используя отражение:
public class TestClass
{
private static MethodInfo innerMethodDefinition =
typeof(TestClass).GetMethod("InnerMethod");
public void Method(object data)
{
var t = data.GetType();
while (t != null &&
!(t.IsGenericType &&
t.GetGenericTypeDefinition() == typeof(BaseType<>)))
{
t = t.BaseType;
}
if (t != null &&
t.GetGenericArguments()[0].IsAssignableFrom(data.GetType()))
{
innerMethodDefinition.MakeGenericMethod(
t.GetGenericArguments()[0]).Invoke(this, new object[] { data });
}
}
public void InnerMethod<TEntity>(TEntity data)
where TEntity : BaseType<TEntity>
{
// Here you have the object with the correct type
}
}