Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

It is possible to have a null params in c#, but why? [duplicate]

Tags:

c#

Output

1

2

null

2

Code

class Program
{        
    static void Main(String[] args)
    {
        String s = null;
        PrintLength(s);
        PrintLength(s, s);
        PrintLength(null);
        PrintLength(null, null);    
        Console.ReadKey();
    }

    private static void PrintLength(params String[] items)
    {
        Console.WriteLine(items == null ? "null" : items.Length.ToString());
    }    
}
like image 527
ChaosPandion Avatar asked Feb 05 '10 21:02

ChaosPandion


People also ask

Can params be null?

So yes, it is entirely possible for the array associated with params to be null.

Can you pass null as a parameter in C?

You can pass NULL as a function parameter only if the specific parameter is a pointer. The only practical way is with a pointer for a parameter.

Can you use null in C?

C, C++, and SQL use the word null, but for different meanings. The C and C++ languages have a null character (NUL), a null pointer (NULL), and a null statement (just a semicolon (;)). The C NUL is a single character that compares equal to 0.

Can you have optional parameters in C?

The C Programming Language has no optional parameters.


3 Answers

This is a fairly frequently asked question. For details, see section 7.4.1 and 7.4.3.1 of the specification.

Briefly: a method with a params array is applicable in either its "normal form" or its "expanded form". That is, you can say

PrintLength(new string[] {"hello"}); // normal form
PrintLength("hello"); // expanded form, translated into normal form by compiler.

When given a call that is applicable in both forms, the compiler always chooses the normal form over the expanded form.

Suppose we chose the expanded form every time both were applicable. Suppose you had

void M(params object[] x) {}

How would you actually pass a null array to this thing if we always chose the expanded form? That would be impossible!

Suppose you said

M(new object[] { "hello" });

and we always chose the expanded form. What would this do? Well, an array of objects is an object, so this would choose the expanded form -- it would make another array, wrap this thing up in the array, and pass that!

The choice of expanded form over normal form leads to crazy results. Always choosing the normal form over the expanded form is the more sensible thing to do.

like image 96
Eric Lippert Avatar answered Oct 17 '22 03:10

Eric Lippert


It works as designed, I'd say:

PrintLength(s);

You're passing in a single string which is null - inside your method, items will not be null - it's an array of one element - of type string - of value null

PrintLength(s, s);

Same story here - you're passing in two elements, so items in your method will be an array of two strings - both of which are null themselves, but the array is not

PrintLength(null);

This obviously gets interpreted as a single NULL value and thus items is null. You're not passing in an array, nor an element of type string - you're just passing in a null value per se.

PrintLength(null, null);

That's again - an array of two elements, both of which are null - but the array per se is not null, since you're passing in two values.

It's a bit puzzling, maybe - but really: what you need to check for in your PrintLength method is not whether your Items as a whole is null - but whether the actual values items[0] and so forth are null.

What is a bit odd maybe - or counter-intuitive at first - is the fact the single explicit "null" value is treated as a "null" - rather than an array of a single item of value null. Why that is the case, and whether it could have been implemented differently - I don't know, quite honestly.

like image 30
marc_s Avatar answered Oct 17 '22 04:10

marc_s


The PrintLength(null) is passing a null array where as PrintLength(null, null) is passing a string[] with a length of two containing two null string objects. It'd be the same as passing new string[] { null, null }

Hmm reading what I wrote maybe that doesn't actually answer your question shrug.

Edit:

This is probably why: You can send a comma-separated list of arguments of the type specified in the parameter declaration, or an array of arguments of the specified type.

http://msdn.microsoft.com/en-us/library/w5zay9db.aspx

like image 37
Cory Charlton Avatar answered Oct 17 '22 05:10

Cory Charlton