在实现的抽象类中转换泛型类型

时间:2014-06-05 10:22:00

标签: c# generics casting abstract-class

我想用一个采用泛型类型的抽象方法创建一个抽象类。我的实现类方法将使用该类型执行某些操作,但因为它的通用我无法访问方法中传递的真实对象的属性。如果我尝试投射,那么它就不会编译,因为你无法转换为T型。我的意思的一个例子。

public abstract class TestAbstractClass
{
    public abstract void Method<T>(ref IQueryable<T> query);
}

public class TestA:TestAbstractClass
{
   // T in this class is an object with a property called Forename
   public override void Method<T>(ref IQueryable<T> query)
   {
       query = query.OrderBy(o=>o.Forename); // unaware of property forename
       query = ((IQueryable<Person>)query).OrderBy(o=>o.Forename); // breaks because of casting
   }
}

public class TestB:TestAbstractClass
{
   // T in this class is an object with a property called HandSize
   public override void Method<T>(ref IQueryable<T> query)
   {
       query = query.OrderBy(o=>o.HandSize); // unaware of property
       query = ((IQueryable<Glove>)query).OrderBy(o=>o.HandSize); // breaks because of casting
   }
}

我希望这是有道理的,我并不是愚蠢的。

干杯

2 个答案:

答案 0 :(得分:5)

解决方案可能是:

public abstract class TestAbstractClass<T>
{
    protected virtual void Method(ref IQueryable<T> query)
    {
    }
}

class TestA : TestAbstractClass<Person>
{
    protected override void Method(ref IQueryable<Person> query)
    {
        var q = query.OrderBy(p => p.Forename);
    }
}

答案 1 :(得分:4)

该代码很脆弱,因为它易于破解。没有人可以通过查看该方法来判断子类只允许一种类型的实体。

有一个名为Liskovs Substitution Principle的原则,它说任何采用基类的方法都应该能够使用任何类型的子类。在这种情况下,<T>说明符可以与object进行比较。

我认为你打算这样做:

public abstract class TestAbstractClass<T>
{
    public abstract void Method(ref IQueryable<T> query);
}

public class TestA : TestAbstractClass<Person>
{
   // T in this class is an object with a property called Forename
   public override void Method(ref IQueryable<T> query)
   {
       query = query.OrderBy(o=>o.Forename); // unaware of property forename
   }
}

public class TestB:TestAbstractClass<Glove>
{
   // T in this class is an object with a property called HandSize
   public override void Method(ref IQueryable<T> query)
   {
       query = query.OrderBy(o=>o.HandSize); // unaware of property
   }
}

不同之处在于您指定整个类只能使用一种允许您获取智能感知的实体类型。