[英]Generic Method gets parameter type from superclass
我在C#中的类型化方法有问题。 我想调用对象的继承方法。 该方法调用以“ this”为参数的静态方法。 静态方法的参数是通用的。 现在,我希望此参数的通用类型是第一个对象的类型。 但是参数始终具有抽象类的类型。
这是示例:
abstract class AbstractClass
{
bool update()
{
Connection.Update(this);
}
}
class Entity : AbstractClass
{
}
class Connection
{
public static void Update<T>(T obj)
{
someMethod<T>()
}
}
如果我尝试这样做:
Entity foo = new Entity();
foo.update();
Connection.Update将在调试器中如下所示:
public static void Update<AbstractClass>(AbstractClass obj)
{
someMethod<AbstractClass>()
}
但是我想要这个:
public static void Update<Entity>(Entity obj)
{
someMethod<Entity>()
}
有没有可能
someMethod<typeof(obj)>()
还是要解决我的问题?
您可以将基类声明为通用类,下面是示例:
abstract class AbstractClass<T>
{
bool update()
{
Connection.Update<T>(this as T);
}
}
class Entity : AbstractClass<Entity>
{
}
class Connection
{
public static void Update<T>(T obj)
{
someMethod<T>()
}
}
如果你想速战速决再投this
以dynamic
,这将延迟类型评估运行。 但是,请考虑使用访客模式。
public bool update()
{
Connection.Update((dynamic)this);
return true;
}
访客模式:
public interface IEntityVisitor
{
void Visit(EntityBase entity);
void Visit(Entity entity);
}
public interface IEntity
{
void Accept(IEntityVisitor visitor);
}
public abstract class EntityBase : IEntity
{
public virtual void Accept(IEntityVisitor visitor)
{
visitor.Visit(this);
}
}
public class Entity : EntityBase
{
public override void Accept(IEntityVisitor visitor)
{
visitor.Visit(this);
}
}
编译器尝试推断T参数的类型,在基类中,编译器没有信息来推断Entity类型。 因此,当您要调用Update函数时,您应该提供子类型的信息。@ Alexandr答案是一个很好的选择,只是对T类型参数添加类型约束以限制它是AbstractClass的子对象的一种改进
abstract class AbstractClass<T>
where T: AbstractClass<T> //restrict T as a child of AbstractClass<T>
{
bool update()
{
Connection.Update<T>(this as T);
}
}
class Entity : AbstractClass<Entity>
{
}
class Connection
{
public static void Update<T>(T obj)
{
someMethod<T>()
}
}
var genericType = typeof(Connection<>);
var specificType = genericType.MakeGenericType(typeof(Entity));
var conn = Activator.CreateInstance(specificType);
像someMethod<typeof(obj)>()
不存在,因为它会破坏C#的类型安全性,因为编译器无法知道参数的运行时类型。 但是,您可以通过调用obj.GetType()
获得真实类型的对象。 您可以使用此类型对象通过反射动态调用方法。
一种解决方案:
abstract class AbstractClass
{
bool update<T>()
{
Connection.Update(T);
}
}
然后,
Entity foo = new Entity();
foo.update<Entity>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.