简体   繁体   English

通用继承类的替代方法,用于将继承的属性约束为其基类型本身的子级

[英]Alternative to generic inherited class to constraint an inherited property to be a child of its base type itself

I want to restrain a member of an inherited class to a specific type. 我想将继承的类的成员限制为特定类型。 I know I could do it with generic class, but it seems more complicated than it should be. 我知道我可以使用泛型类来做到这一点,但似乎比应该做的要复杂得多。 So, here's an exemple. 所以,这是一个例子。

public class Shape
{
    public Texture texture { get; set; }
}

public class Texture { ... }
public class SpecficTexture : Texture { ... }

public class SpecificShape : Shape
{
    public SpecificShape()
    {
        texture = new SpecficTexture();
    }
}

Essentially, in my case I need to implement the class SpecificShape. 本质上,就我而言,我需要实现类SpecificShape。 It's all good but the texture property inside SpecificShape is not known as a specific texture. 一切都很好,但是SpecificShape中的纹理属性不称为特定纹理。 From the SpecificShape, it need to be known as such. 从SpecificShape,它需要这样被知道。 Obviously, I could have the following classes instead. 显然,我可以改用以下类。

public class Shape2<T> where T : Texture
{
    public T texture { get; set; }
}

public class SpecifShape2 : Shape2<SpecficTexture> { ... }

I see two solutions to my problem. 我看到了两种解决方案。 Either I go to my team to switch to make Shape a generic class or I cast texture to SpecificTexture whenever I need it. 我要么去我的团队切换以使Shape成为通用类,要么在需要时将纹理投射到SpecificTexture。 Is there any other way? 还有其他办法吗?

I don't like the idea of casting, it doesn't seem elegant to me, and I'm worried about performance issue if I had to do it multiple times. 我不喜欢强制转换的想法,对我来说似乎并不优雅,而且我担心不得不多次执行性能问题。 At the same time, I'm not sure it's justified to change back what was already implemented. 同时,我不确定更改已实施的内容是否合理。

You can make the texture property virtual in the Shape , override it in SpecificShape and limit the casting to one specific place: 您可以在Shape中将texture属性设为虚拟,在SpecificShape中将其覆盖并将铸造限制在一个特定位置:

public class Shape
{
    public virtual Texture texture { get; set; }
}

public class SpecificShape : Shape
{
    public SpecificTexture specificTexture { get; set; }

    public override Texture texture
    {
        get { return specificTexture; }
        set
        {
            if (value is SpecificTexture specificValue) //this is the only place we have to have a cast
            {
                specificTexture = specificValue;
            }
            else
            {
                //handle error, throw exception, Debug.Assert, or something
            }
        }
    }

    public SpecificShape()
    {
        specificTexture = new SpecificTexture();
    }
}

Whenever you need to use SpecificTexture in your SpecificShape class, you can simply use the specificTexture property instead of texture . 每当需要在SpecificShape类中使用SpecificTexture时,都可以简单地使用specificTexture属性而不是texture

Furthermore, if the parent Shape class doesn't really need the texture property setter (perhaps, the texture property is only set once in the constructor?), then just get rid of the setter, and you can avoid any casts. 此外,如果父Shape类实际上不需要texture属性设置器(也许在构造函数中仅设置一次texture属性?),则只需摆脱设置器,就可以避免进行任何强制转换。

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

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