Generic Method从超类获取参数类型

时间:2014-01-31 13:31:23

标签: c# generics inheritance this

我在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)>()

或其他什么来解决我的问题?

6 个答案:

答案 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>();
相关问题