我在C#中使用类型化方法时遇到问题。 我想调用一个对象的继承方法。 这个方法用"这个"调用静态方法。作为参数。 静态方法的参数是通用的。 我现在希望此参数的泛型类型是第一个对象的类型。 但参数始终是抽象类的类型。
以下是示例:
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)>()
或其他什么来解决我的问题?
答案 0 :(得分:3)
您可以将基类声明为通用基类,以下是示例:
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>()
}
}
答案 1 :(得分:1)
如果您想快速修复,请将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);
}
}
答案 2 :(得分:1)
编译器尝试推断T参数的类型,在基类中它没有推断实体类型的信息。因此,当您想要调用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>()
}
}
答案 3 :(得分:0)
var genericType = typeof(Connection<>);
var specificType = genericType.MakeGenericType(typeof(Entity));
var conn = Activator.CreateInstance(specificType);
答案 4 :(得分:0)
someMethod<typeof(obj)>()
之类的东西不存在,因为它会破坏C#的类型安全性,因为编译器无法知道参数的运行时类型。但是,您可以通过调用obj.GetType()
来获取真实类型对象。您可以使用此类型对象使用Reflection动态调用方法。
答案 5 :(得分:0)
有一个解决方案:
abstract class AbstractClass
{
bool update<T>()
{
Connection.Update(T);
}
}
然后,
Entity foo = new Entity();
foo.update<Entity>();