Instance Methods on Null References

snarfblam

Ultimate Contributor
Joined
Jun 10, 2003
Messages
2,097
Location
USA
This is just a thought I had. I don't expect, or even really hope, that it should happen. Just sharing some thoughts, I suppose.

A somewhat novel idea occurred to me. At runtime, the only thing that actually stops the CLR from invoking an instance method on a null reference is a runtime check for a null value. If such a check were removed, we could invoke a non-virtual instance method on a null reference, resulting in a this pointer with a null value. The natural question would be, "What person in their right mind would want to call instance methods on nothing in particular an OOP language?"

There are times, however, when this could be handy. Consider a common problem with strings. We might assume a string variable has a value, even if the value is empty. This mistake can result is a null reference exception when we check the length of a string, change its case, or call the instance Equals method. With "nullable" string methods, however, we could write a Length property that looked like this:
C#:
// nullable keyword to declare intent to allow null references
public nullable int Length{ 
    get{
        if(this == null)
            return 0;
        else
            return charbuffer.Length;
    }
}
The behavior we achieve here is that even if we read the Length property on a null reference, we get the intuitive return value of zero. Of course, this "feature" would not be without drawbacks. We take the non-null value of the this pointer for granted, and especially with unqualified class members, it would be all too easy to add null-reference exceptions to your program instead of reducing them.

So, am I the only who cooks up wacky programming features, or does anyone else have anything to add?
 
Language ideas

Good thread! :cool:

There are times, however, when this could be handy. Consider a common problem with strings. We might assume a string variable has a value, even if the value is empty.

The string can be considered to be essentially a value type which is implemented as a reference type. This is evident from the fact that it is immutable and has overloaded equality operators. Therefore in this case I suppose it would make some sense to have a nullable keyword as you describe. However, it would make most sense to be a class-level declaration rather than a method-level one, as it would become quite confusing if some methods could be called on null references and others not.

So, am I the only who cooks up wacky programming features, or does anyone else have anything to add?

I have often considered that a nonull keyword would be useful:

C#:
void EatCake(nonull Cake someCake)
{
    //Method body
}

What this would do is cause the compiler to generate a check that the someCake argument is not null and throw an ArgumentNullException with the appropriate message if it is. On the meta-data side it could also mean that the compiler does not allow null to be passed (explicitly) to nonull parameters.

Another language feature I would like would be the ability to break out of multiple blocks in one statement:

C#:
for (int x = 0; x < rows; x++) {
    for (int y = 0; y < cols; y++) {
        if (someCondition)
            break break;
    }
}

In this case the two break statements would cause execution to break out of both for loops - it would work for all kinds of break-able blocks and as many break statements could be added together as required. It would not introduce spaghetti-code any more than the existing single break statements do, and would save having to create dummy finished boolean variables.

I could probably think up some more given time. :)
 
marble, your idea sounds similar to the pattern of "nullable types" offered up my the Martin Fowler refactoring book. I tend to think of it as a "missing type," but the idea is the same. Introduce an inherited "Missing" object. Here's the idea:

Define interface IMissing, which exposes one property: bool IsMissing.
Create your Customer class, implemented the IMissing interface. The IsMissing property always returns false.
Create your CustomerMissing class, inheriting from Customer. The IsMissing property always returns true. You provide "reasonable defaults" for any properties you want. Implies that you've marked the properties or methods as virtual in the base Customer class.

So in code, a variable of type "Customer" would NEVER be null. This is generally enforced through a factory method that returns either Customer or CustomerMissing (which will also generally use the Singleton pattern).

That's a lot of work for a simple "string" override - but sounds very similar in ideas. I think it might be useful to have "reasonable defaults" for some of the instance methods.

Code:
Now for something almost but not completely different
I had this conversation with a friend the other day - how nice would it be to allow calling "static" methods on an instance variable? The one that came to mind was string.IsNullOrEmpty(var) which I hate because of it's readability. Here's what you have now:
if (string.IsNullOrEmpty(lastName)) {...}

What I think would be infinitely better is:
if (lastName.IsNullOrEmpty()) {...}

The problem, of course, is that if "lastName" is null you'd get a null reference exception. Hence, the IsNullOrEmpty would either have to be special or a static method. Two problems with static: .Net doesn't allow static method calls on an instance variable AND a static method wouldn't know about the instance variable such as lastName above.

Now here's the "AHA!" moment. DotNet has already imlemented this functionality for nullable types so I *KNOW* that it can be done! Take this example, which works:
C#:
int? age = null;
if (age.HasValue)
{
    ...
}

Notice anything odd, or unexpected? You mean besides the fact that HasValue is a property being called on an instance variable that's null and you DO NOT get a null reference? Weird, but I *WANT* that behavior on my strings!!!

That's all.

-ner
 
Nerseus, you make a good point with DotNet nullable types. The trick with the Nullable type, however, is that it is a struct, and is never truly a null reference. To achieve this type of functionality in a more general way, it would require wrapping any classes where this behavior is desired in a struct, which brings up another interesting idea. For the incredibly common class, string, it might be reasonable (or, probably not) to write such a struct-based wrapper.
C#:
// (Incomplete) class that wraps a System.String object and eliminates 
// the possibility of a null reference. It is implicitly castable to and from
// System.String, so it can be used transparently and interchangeably with
// System.String objects.
struct SillyString
{
    string value;
    public string Value {
        get {
            if (value == null)
                value = string.Empty;

            return value;
        }
    }
    public SillyString(string value) {
        this.value = value;
    }
    public static implicit operator string(SillyString value) {
        if (value.value == null)
            return string.Empty;
        else
            return value.value;
    }
    public static implicit operator SillyString(string value) {
        if (value == null)
            return new SillyString(string.Empty);
        else
            return new SillyString(value);
    }

    public static readonly SillyString Empty = string.Empty;
    public int Length { get { return Value.Length; } }
    public Char this[int i] { get { return value[i]; } }
    public SillyString Clone() { return this; }
    public int CompareTo(string value) {
        return Value.CompareTo(value);
    }
}
The SillyString might be nice, but would probably prove to be superfluous, imposing a performance tax and with only occasional benefit, but to be perfectly honest, I do find myself running into NullReferenceExceptions with strings from time to time, although they are very easy to debug.

As for the nullable pattern, it does seem overly elaborate for general use, and I don't see how the pattern could possibly be enforced in C#. Unless I'm missing something, it would require that a programmer make proper use of it, or the null reference exceptions would persist.

MrPaul, perhaps the Nullable keyword should be applicable to either a type or a member. You are right in thinking that this is a concept that would generally be applied to a type as a whole, but sometimes it might be more appropriate to apply only to one or two members.

The nonull feature would be a nice convenience, but, then, there are lots of prerequisites that it might be nice to enforce using a nifty keyword or syntax, such as non-zero or positive integers, and exclusion of NaN and infinity values for floating point numbers. As for the extended behavior of the break keyword, I personally think that this is something that C# sorely lacks.
 
Not sure where I read it but I think extension methods in C# 3 allow you to do this kind of thing i.e.

C#:
public namespace Sample{
public static class SampleExtensions 
{
public static int StringLength(this string aString) 
    {
    if(this == null)
        return 0;
    else
        return aString.Length;
    }
  } 
}
This could then be used like
C#:
using Sample.SampleExtensions;

void Method1()
{
string s = null;

int i = s.StringLength();
}

syntax might be off as I don't have any version of VS here, never mind a copy of Orcas installed ;)
 
But I don't like extenders. Don't you remember my long, whiny post about C# 3.0 features?
 
Back
Top