如何指定要使用其类型的子类

本文关键字:类型 子类 何指定 | 更新日期: 2023-09-27 18:10:42

假设我有这样一个类:

public abstract class Foo
{
    public void Access(Foo foo)
    {
        /*
        if (foo is same type as implemented)
            AccessIfSameImplementation(foo);
        else
            AccessIfDifferentImplementation(foo);
        */
    }
    protected abstract void AccessIfSameImplementation(Foo foo);
    private void AccessIfDifferentImplementation(Foo foo)
    {
         //do stuff with the different implementations
    }
}

因此,方法Access本身就有一种类型,根据定义,只要它继承自Foo,我们就不会真正关心它是什么。。。但我希望此方法检查传入的对象是否与其实现的类型相同。

像这样:

public class Bar : Foo
{
    protected override void AccessIfSameImplementation(Foo foo)
    {
        // TODO: How do I force foo to always be a Bar
        // do specific Bar stuff
    }
}

目前,我有一个Name字段,它指示传入的foo.Name是否与当前的Name相同。此外,我曾想过使用泛型,但再次认为这不是解决这个问题的正确方法。

编辑:

关于我正在使用的实际结构的一些背景知识。

上面定义的Foo类代表创建一组对象List<X> objs的工厂,这些对象是由实现的Foo对象的属性生成的。现在我有一些其他类比较这些工厂,但我不希望这些工厂因为全部生产而变得臃肿。因此,我不想让工厂膨胀,而是简单地检查它们是否有相同的实现,如果是,则比较抽象比较器定义的属性,否则就会井喷。稍后有时间我会添加更多内容。

如果有人有更好的头衔,请推荐一个。

如何指定要使用其类型的子类

空着,所以我想我就是想不透。所有需要做的就是直接在公共方法Access 中进行类型比较

public void Access(Foo foo)
{
    if (GetType() == foo.GetType) //Duh...
    {
         AccessIfSameImplementation(foo);
    }
    else
    {
         AccessIfDifferentImplementation(foo);
    }
}

我不完全确定您的意图是什么,但您不能更改子类中抽象方法的签名。一个想法是,如果你得到了一个不合适的foo:,就进行参数检查并抛出异常

public abstract class Foo
{
    public void Access(Foo foo)
    {
        if (foo.GetType() == GetType())
        {
            AccessIfSameImplementation(foo);
        }
        else
        {
            AccessIfDifferentImplementation(foo);
        }
    }
    protected abstract void AccessIfSameImplementation(Foo foo);
    private void AccessIfDifferentImplementation(Foo foo)
    {
        //do stuff with the different implementations
    }
}
public class Bar : Foo
{
    public string Baz { get; set; }
    protected override void AccessIfSameImplementation(Foo foo)
    {
        var bar = foo as Bar;
        if (bar == null)
        {
            throw new ArgumentException("Argument foo is not of type Bar");
        }
        //Do Bar stuff below
        bar.Baz = "Yay!";
    }
}

保持简单。保持抽象类的抽象性,但为Access方法提供一个与Foo无关的默认实现。让它作为一个子类来提供使用该子类成员的自定义实现。您还可以使子类可以选择返回基类中实现的默认逻辑:

public abstract class Foo
{
    public virtual void Access(Foo foo)
    {
        // perform the default implementation here, but mark as virtual to enable a child class to override it.
    }
}
public class Bar : Foo
{
    public override void Access(Foo foo)
    {
        var bar = foo as Bar;
        if (bar != null)
        {
            // If you get here, that means foo is a Bar.
            // Just use bar now and ignore foo.
        }
        else
        {
            // Fall back on the base classes implementation
            base.Access(foo);
        }
    }
}