简体   繁体   English

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

[英]Casting a Generic Type in implemented abstract class

I wanted to create an abstract class with an abstract method that takes a generic type. 我想用一个采用通用类型的抽象方法创建一个抽象类。 My implementing class method will do something with that type but because its generic I dont have access to the properties of the real object thats passed in the method. 我的实现类方法将对该类型执行某些操作,但是由于其泛型,我无法访问该方法中传递的真实对象的属性。 If I try casting then it won't compile as you cant cast back to a T type. 如果我尝试强制转换,那么它将无法编译,因为您无法强制转换回T类型。 An example of my meaning. 我的意思的一个例子。

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
   }
}

I hope this makes sense and I'm not being stupid. 我希望这是有道理的,而且我也不会傻。

Cheers 干杯

A solution could be: 解决方案可能是:

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);
    }
}

That code is fragile as it's easy to break it. 该代码很脆弱,因为很容易破坏它。 No one can tell by looking at that method that the sub class only allows one type of entity. 通过查看该方法,没有人能知道子类仅允许一种类型的实体。

There is a principle called Liskovs Substitution Principle which says that any method that takes a base class should be able to work with any kind of subclass. 有一个称为Liskovs Substitution Principle的原则,该原则表示,采用基类的任何方法都应能够与任何种类的子类一起使用。 In this case the <T> specifier could be compared to object . 在这种情况下,可以将<T>说明符与object进行比较。

I think that you meant to do this: 我认为您打算这样做:

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
   }
}

The difference is that you specify that the entire class can only work with one type of entity which allows you to get intellisense etc. 区别在于,您指定整个类只能与一种类型的实体一起使用,从而使您可以获取智能感知等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM