0

假设我有这样的课程:

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对象的属性生成。现在我有一些其他类比较这些工厂,但我不希望工厂因为生成它们而变得臃​​肿。因此,我不是*使工厂膨胀,而是检查它们是否具有相同的实现,如果是,则比较抽象比较器定义的属性,否则 *blowout。以后有时间我会补充的。

如果有人有更好的标题,请推荐一个。

4

3 回答 3

2

好吧,所以我想我只是无法完全思考问题。只需在公共方法中直接进行类型比较Access

public void Access(Foo foo)
{
    if (GetType() == foo.GetType) //Duh...
    {
         AccessIfSameImplementation(foo);
    }
    else
    {
         AccessIfDifferentImplementation(foo);
    }
}
于 2013-04-25T01:27:20.213 回答
1

我不完全确定您的意图是什么,但是您不能更改子类中抽象方法的签名。一个想法是做一个参数检查,如果你有一个不合适的 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!";
    }
}
于 2013-04-25T01:07:30.923 回答
1

把事情简单化。保持抽象类抽象,但给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);
        }
    }
}
于 2013-04-25T01:38:14.870 回答