Inheritance comment / question -- change visibility of Delete method

Inheritance comment / question -- change visibility of Delete method

Old forum URL: forums.lhotka.net/forums/t/3757.aspx


lazaropi posted on Monday, October 22, 2007

Hi,

The BusinessBase class is great most of the time, but I have a couple of BO's for which I would like to "turn off" the delete method (these objects can be modified but they should never be deleted from the DB.

It turns out that C# is a lot more restrictive than C++ when it comes to inheritance (almost always with good cause). In this case, it is impossible to override a member with a different visibility.

At first I thought that the 'new' keyword would help by hiding the base member and declaring the new one with private modifier. That does not work. The 'new' only hides a member with the exact same signature so the base method is still accessible.

The best I can do so far is to override delete( ) with an empty definition so it does not do anything.

something like this:

        public override void Delete( )
        {
            // the only way to prevent the delete is to do nothing here
            // it is still possible to call
            // base.Delete( );
            // to get the delete method of the BusinessObject class
            // when this is done an exception is thrown because there is
            // no delete functionality implemented in the DB.
            // we don't want these records to be deleted.
        }

Have any of you guys ever come up with this issue? If so, what would be a better way to deal with it?

thanks,

lazz pi

lazaropi replied on Monday, October 22, 2007

Just to clarify the 'new' keyword part:

You can check that 'new' doesn't work here (despite what I found through a Google search)

    public class BaseClass
    {
        public virtual void MyMethod( )
        {
            Console.WriteLine( "From Base" );
        }
    }

    public class DerivedClass : BaseClass
    {
        private new void MyMethod( )
        {
            Console.WriteLine( "From Derived" );
        }
        public void OtherMethod( )
        {
            Console.WriteLine( "From Other" );
        }
    }

    public class User
    {
        public static void WorkHere( )
        {
            DerivedClass dc = new DerivedClass( );
            dc.MyMethod( ); //still calling base class method
            dc.OtherMethod( );
            BaseClass bc = ( BaseClass ) dc;
            bc.MyMethod( );
        }
    }

ajj3085 replied on Monday, October 22, 2007

Your best bet is to override Delete and throw a NotSupportedException.

You could also override Save and throw a NotSupportedException if IsDeleted is set to true as well.

lazaropi replied on Monday, October 22, 2007

Thanks for your replay, I'd say that would do it but what I would really like is for the Delete method not to be available to the class user.

It is another case of trade offs in language design, I guess.

ajj3085 replied on Monday, October 22, 2007

To make it unavailable, you'd have create something between what is in BusinessBase and BindableBase now in Csla.Core.  Then you could have a NonDeletableBusiness base, and inherit from that.  BusinessBase would also inhert this new class, and just add the deleting portion of code.

Well, at least that's an off the top of my head way to do it. 

Along the suggestion from my first post, you could subclass Csla.BusinessBase to a NonDeletableBusinessBase and do the overrides there... that would save having to override Delete in every class in which you don't want to support deletions.

So if you really want it gone, you should be able to.. its just a matter of if you want to spend the time (now and later) coding that.

lazaropi replied on Monday, October 22, 2007

Right, that's precisely what I'm talking about. It is just too much work to get so little. And that's why I sort of miss the more carefree (dangerous) approach of other pardigms.

Having said that, I really like the overall design choices of C# and .NET. It is my preferred language, environment (at least for now).

Thanks for your comments,

lazz pi

Henrik replied on Tuesday, October 23, 2007

Several times I've found myself in the same position where the businessbase offers a method, say delete or update, that the use case didn't need or should support.

I just as many cases I've found myself implementing the very same methods later on, when the business rules changes.

My point is, that it's better to have the Delete method in the business base and just throw a NotSupportedException, than building a separate base class without the method. If the business rules,  later on suddenly requires the delete method you can just implement the method instead of inheriting from a new base class which can easily introduce bugs in other parts of the class.

You can also have the case where the user cannot execute the method but an admin can. However in these cases there is often talk about two different use cases and thus two different business object.

In the end you should remember that it's the application developers that can see the delete method and not the end user. It's way easier to teach application developers not to call the delete method by throwing an exception in their face than teaching an end user not to press the delete button ;-)

Hope this helps a bit.

Cheers
/Henrik

lazaropi replied on Wednesday, October 24, 2007

Well, your point makes a lot of sense. I think I'll do it with an exception.

BTW, there are other situations where the object has to sometimes allow some behavior and sometimes it can't (according to some criteria) but must of the time it can be handled with validation / authorization rules. But the logic can become quite complex and in the end one has to decide these things in a case by case basis.

Thanks!

lazz pi

Copyright (c) Marimer LLC