Question

Lets say I have a class such as this:

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

So the method Access takes a type of itself, by definition it will be an implementation in which we don't really care what it is as long as it inherits from Foo... But I want this method to check if the object passed in is the same type as its implementation.

Like so:

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

Currently I have a Name field that indicates if the passed in foo.Name is the same as the current Name Besides that I thought about using generics but again don't think that's the right approach to this problem.

EDIT:

A little background on the actual structures I'm using.

The Foo class defined above is representative of a factory that creates a set of objects List<X> objs these objects are generated by the properties of the implemented Foo object. Now I have some other class comparing these factories but I don't wish for the factories to be, *bloated out by generating them all. So instead of *bloating the factories out I simply check if they have the same implementation, if so compare properties defined by the abstract comparer otherwise *blowout. I will add more later when I have some time.

If anyone has a better title please recommend one.

Was it helpful?

Solution

Aright so I guess I just can't think things entirely through. All that needs to be done is a type comparison directly in the public method Access

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

OTHER TIPS

I'm not totally sure what your intention is, but you can't change the signature of an abstract method in the child class. One thought would be to do an argument check and throw an exception if you ever got an inappropriate 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!";
    }
}

Keep it simple. Keep your abstract class abstract, but give the Access method a default implementation that is Foo agnostic. Leave it up the a child class to provide custom implementation that uses members of that child class. You could also make it optional for the child class to fall back on the default logic implemented in the base class:

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);
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top