我的情况很混乱。
基础通用类型和后继者
public abstract class BaseType<TEntity> : where TEntity : BaseType<TEntity>
public class AnyType : BaseType<AnyType>
看起来像一个通用循环)))
我需要像
这样的方法public void Method<T>(T data)
{
if(typeof(T).IsSubclassOf(BaseType<????>))
convert data to BaseType<???> and exec BaseType<>'s method
else
//Do that
}
在泛型方法中,我需要定义T是BaseType和exec方法。 我怎么能这样做????
答案 0 :(得分:1)
您可以使用反射,并使用Type.BaseType
在层次结构中向上工作。请注意,根据具体的具体类,基类型仍然可以是开放的泛型类型,例如
class Foo<T> : BaseType<T>
您可以使用Type.IsGenericTypeDefinition
和Type.GetGenericTypeDefinition
尝试前往BaseType<>
。基本上,您希望了解继承层次结构中的任何类是否具有typeof(BaseType<>)
的泛型类型定义。只是很高兴你没有处理接口,这使整个事情变得更加困难:)
答案 1 :(得分:1)
您可以使用以下代码:
static bool IsBaseType<T>()
{
var t = typeof(T);
do
{
if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(BaseType<>))
{
return true;
}
t = t.BaseType;
}
while (t != null);
return false;
}
答案 2 :(得分:0)
在这种情况下,常见的模式是具有通用基类型的非泛型基类型。如果您的方法不涉及类型参数,那么您就完成了。如果是,您可以添加一个非泛型方法进行类型转换,类似于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
}
}