4 ms·
I would make the public version of Save a static method on an abstract class (or a static method in a utility class) and avoid the whole worry over null. It's o
by noblethrasher 16y ago
I would make the public version of Save a static method on an abstract class (or a static method in a utility class) and avoid the whole worry over null. It's only a bit more work up front.
abstract class Foo
{
public static Result Save(Foo foo)
{
if(foo != null)
foo._Save();
else
{
//Do Stuff...
}
}
protected abstract Result _Save();
}
Then use like so,
foreach(Foo s in xs)
{
Foo.Save(s); //or s.Save() if Save() is an extension method.
}
- danparsonson 16y agoOr use an interface, then anyone making changes further down the line could leave the 'Save()' calling code alone entirely.
- noblethrasher 16y agoThat would work too but an abstract class let's you keep the _save method private so that client code can't possibly call that instance method on null. Personally I think that now that we have extension methods, all public methods should be extension methods on interfaces or abstract classes. This basically gives you something like the pattern matching in ML and Haskell.
- jbrechtel 16y agoThis misses the author's point. In his example the bug you want to detect is that the referenced object in question is not a Customer (or a Foo in your example). In your else block you can't report anymore information than the NullPointerException in the author's original example reported. If you still use an 'as' operator at the callsite then you've lost all useful information. If you do a cast then you'll at least get an exception with WHAT it was you were trying to cast.
- noblethrasher 16y agoI don’t think that I’ve missed the author's point; but any time I see an if statement and polymorphic code used near each other, I question whether or not the programmer understands OOP. His example is not exactly using polymorphic code, but he is basically dispatching based on the runtime type. We know that a method that accepts parameters that are reference types should check to see if they are null. Since instance methods cannot check their first parameter (the this pointer), we make it impossible for outside code to call instance methods. Now callers never have to worry about the runtime type of an object or whether or not it’s null. If you’re going to circumvent the type system with explicit casts then, of course, you’re going to get invalid cast exceptions, but that’s for the client code to deal with.