default values

  • Thread starter Thread starter John Wood
  • Start date Start date
J

John Wood

Even though CSC does its best to detect use of unassigned variables, it
often misses it... for example if you just declare a double in a class
without assigning a default value, it has a default value of 0 and lets you
use it anyway.

My question is, how can I retrieve the default value for a given type? The
CLR obviously has these defaults stored somewhere and I was hoping to get
hold of it.

I hoped the following code would work, but TypeInitializer is null:

double d = 12;
ConstructorInfo con = d.GetType().TypeInitializer;
Console.WriteLine(con.Invoke(new object[] { }));

Any ideas?
 
John,
My question is, how can I retrieve the default value for a given type?

The default is all bits zeroed out, meaning 0 or 0.0 for numeric
types, false for bools and null for reference types.

For value types, you get the default value when using the default
constructor.

double d = new double(); // effectively the same as double d = 0.0;



Mattias
 
Yes, that may be true -- but, given an arbitrary value type, how do I
programmatically retrieve the default value for that type? It can't just be
0 bits, because for a string (for example) that won't work.

I'd have hoped that the boxed equivalent of the value type would have a
constructor, but GetConstructor returns null.
 
John,

It's actually quite simple. You can use reflection to determine whether
or not the type derives from ValueType in some way. If it does, then you
can just use the default constructor to generate a value with the bits
zeroed out. If it does not derive from ValueType, then it is a reference
type, and the default value is null.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

John Wood said:
Yes, that may be true -- but, given an arbitrary value type, how do I
programmatically retrieve the default value for that type? It can't just be
0 bits, because for a string (for example) that won't work.

I'd have hoped that the boxed equivalent of the value type would have a
constructor, but GetConstructor returns null.
 
Right, but that won't work for Guid, DateTime or String (to name a few).
Isn't there a method somewhere in the framework that just returns the
default value for a given type?

Nicholas Paldino said:
John,

It's actually quite simple. You can use reflection to determine whether
or not the type derives from ValueType in some way. If it does, then you
can just use the default constructor to generate a value with the bits
zeroed out. If it does not derive from ValueType, then it is a reference
type, and the default value is null.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

John Wood said:
Yes, that may be true -- but, given an arbitrary value type, how do I
programmatically retrieve the default value for that type? It can't
just
 
John,

Yes, actually it would. With Guid and DateTime, since they are
structures, they have default constructors, which you can get through
reflection and call through reflection (once you have the type).

With a string, it is not a value type, so the default value for a string
is null, which the algorithm that I detailed in my previous post will return
to you.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

John Wood said:
Right, but that won't work for Guid, DateTime or String (to name a few).
Isn't there a method somewhere in the framework that just returns the
default value for a given type?

message news:[email protected]...
John,

It's actually quite simple. You can use reflection to determine whether
or not the type derives from ValueType in some way. If it does, then you
can just use the default constructor to generate a value with the bits
zeroed out. If it does not derive from ValueType, then it is a reference
type, and the default value is null.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

John Wood said:
Yes, that may be true -- but, given an arbitrary value type, how do I
programmatically retrieve the default value for that type? It can't
just
be
0 bits, because for a string (for example) that won't work.

I'd have hoped that the boxed equivalent of the value type would have a
constructor, but GetConstructor returns null.

John,

My question is, how can I retrieve the default value for a given type?

The default is all bits zeroed out, meaning 0 or 0.0 for numeric
types, false for bools and null for reference types.

For value types, you get the default value when using the default
constructor.

double d = new double(); // effectively the same as double d = 0.0;



Mattias
 
Nicholas Paldino said:
John,

It's actually quite simple. You can use reflection to determine
whether
or not the type derives from ValueType in some way. If it does, then you
can just use the default constructor to generate a value with the bits
zeroed out. If it does not derive from ValueType, then it is a reference
type, and the default value is null.

The only problem is most value types don't have default constructors(I think
MC++ allowed this for a while, but don't think any other languages did). The
new int() style syntax supported by C# is actually a syntactic sugar for the
initobj instruction, which tells the CLR to zero out a given value type.
Unfortunatly the langage as it stands doesn't support any syntax to
initialize a variable to its default. Tthe C# 2.0 .default operator should
give the behaviour the OP is looking for, if I understand him correctly, but
I havn't taken the time to verify it again in the spec preview so it could
just be an artifact of the current build, but I don't think so.
Hope this helps.
 
If you run GetConstructor on the value type it returns null though...
doesn't look like any of the value types can provide a default constructor.

Nicholas Paldino said:
John,

Yes, actually it would. With Guid and DateTime, since they are
structures, they have default constructors, which you can get through
reflection and call through reflection (once you have the type).

With a string, it is not a value type, so the default value for a string
is null, which the algorithm that I detailed in my previous post will return
to you.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

John Wood said:
Right, but that won't work for Guid, DateTime or String (to name a few).
Isn't there a method somewhere in the framework that just returns the
default value for a given type?

message news:[email protected]...
John,

It's actually quite simple. You can use reflection to determine whether
or not the type derives from ValueType in some way. If it does, then you
can just use the default constructor to generate a value with the bits
zeroed out. If it does not derive from ValueType, then it is a reference
type, and the default value is null.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Yes, that may be true -- but, given an arbitrary value type, how do I
programmatically retrieve the default value for that type? It can't just
be
0 bits, because for a string (for example) that won't work.

I'd have hoped that the boxed equivalent of the value type would
have
 
I suppose this answers my question... although it's disappointing the
initobj instruction isn't exposed through the language.

Thanks.

Daniel O'Connell said:
message news:[email protected]...
John,

It's actually quite simple. You can use reflection to determine
whether
or not the type derives from ValueType in some way. If it does, then you
can just use the default constructor to generate a value with the bits
zeroed out. If it does not derive from ValueType, then it is a reference
type, and the default value is null.

The only problem is most value types don't have default constructors(I think
MC++ allowed this for a while, but don't think any other languages did). The
new int() style syntax supported by C# is actually a syntactic sugar for the
initobj instruction, which tells the CLR to zero out a given value type.
Unfortunatly the langage as it stands doesn't support any syntax to
initialize a variable to its default. Tthe C# 2.0 .default operator should
give the behaviour the OP is looking for, if I understand him correctly, but
I havn't taken the time to verify it again in the spec preview so it could
just be an artifact of the current build, but I don't think so.
Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

John Wood said:
Yes, that may be true -- but, given an arbitrary value type, how do I
programmatically retrieve the default value for that type? It can't
just
be
0 bits, because for a string (for example) that won't work.

I'd have hoped that the boxed equivalent of the value type would have a
constructor, but GetConstructor returns null.

John,

My question is, how can I retrieve the default value for a given type?

The default is all bits zeroed out, meaning 0 or 0.0 for numeric
types, false for bools and null for reference types.

For value types, you get the default value when using the default
constructor.

double d = new double(); // effectively the same as double d = 0.0;



Mattias
 
John,

You actually don't need to get a constructor, you can just call the
version of CreateInstance that takes just the type, it will create an
instance with the bits zeroed out, like this:

// Get the type.
Type pobjIntType = typeof(int);

// Create an instance.
object pobjInt = Activator.CreateInstance(pobjIntType);

Of course, you only run this code if you have a value type, otherwise,
you just return null (for reference types). The full code I would use is:

public static object GetDefaultValue(Type type)
{
// If type is null, throw an exception.
if (type == null)
// Throw an exception.
throw new ArgumentNullException("type");

// Check to see if the type is a value type.
// If it is not, return null.
if (!type.IsValueType)
// Return null.
return null;

// Create an instance of the value type.
return Activator.CreateInstance(type);
}


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

John Wood said:
If you run GetConstructor on the value type it returns null though...
doesn't look like any of the value types can provide a default constructor.

message news:[email protected]...
John,

Yes, actually it would. With Guid and DateTime, since they are
structures, they have default constructors, which you can get through
reflection and call through reflection (once you have the type).

With a string, it is not a value type, so the default value for a string
is null, which the algorithm that I detailed in my previous post will return
to you.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

John Wood said:
Right, but that won't work for Guid, DateTime or String (to name a few).
Isn't there a method somewhere in the framework that just returns the
default value for a given type?

"Nicholas Paldino [.NET/C# MVP]" <[email protected]>
wrote
in
message John,

It's actually quite simple. You can use reflection to determine
whether
or not the type derives from ValueType in some way. If it does,
then
you
can just use the default constructor to generate a value with the bits
zeroed out. If it does not derive from ValueType, then it is a reference
type, and the default value is null.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Yes, that may be true -- but, given an arbitrary value type, how
do
 
Daniel,

While you can not get a default constructor in .NET through reflection,
you can still create a default instance of the value type through the static
CreateInstance method on the Activator class. You just have to pass the
type and it will know what to do with it.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Daniel O'Connell said:
message news:[email protected]...
John,

It's actually quite simple. You can use reflection to determine
whether
or not the type derives from ValueType in some way. If it does, then you
can just use the default constructor to generate a value with the bits
zeroed out. If it does not derive from ValueType, then it is a reference
type, and the default value is null.

The only problem is most value types don't have default constructors(I think
MC++ allowed this for a while, but don't think any other languages did). The
new int() style syntax supported by C# is actually a syntactic sugar for the
initobj instruction, which tells the CLR to zero out a given value type.
Unfortunatly the langage as it stands doesn't support any syntax to
initialize a variable to its default. Tthe C# 2.0 .default operator should
give the behaviour the OP is looking for, if I understand him correctly, but
I havn't taken the time to verify it again in the spec preview so it could
just be an artifact of the current build, but I don't think so.
Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

John Wood said:
Yes, that may be true -- but, given an arbitrary value type, how do I
programmatically retrieve the default value for that type? It can't
just
be
0 bits, because for a string (for example) that won't work.

I'd have hoped that the boxed equivalent of the value type would have a
constructor, but GetConstructor returns null.

John,

My question is, how can I retrieve the default value for a given type?

The default is all bits zeroed out, meaning 0 or 0.0 for numeric
types, false for bools and null for reference types.

For value types, you get the default value when using the default
constructor.

double d = new double(); // effectively the same as double d = 0.0;



Mattias
 
Nicholas Paldino said:
Daniel,

While you can not get a default constructor in .NET through reflection,
you can still create a default instance of the value type through the
static
CreateInstance method on the Activator class. You just have to pass the
type and it will know what to do with it.

Yeah...most likely its using initobj at that, :). I wasn't considering
Activator.CreateInstance.
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Daniel O'Connell said:
message news:[email protected]...
John,

It's actually quite simple. You can use reflection to determine
whether
or not the type derives from ValueType in some way. If it does, then you
can just use the default constructor to generate a value with the bits
zeroed out. If it does not derive from ValueType, then it is a reference
type, and the default value is null.

The only problem is most value types don't have default constructors(I think
MC++ allowed this for a while, but don't think any other languages did). The
new int() style syntax supported by C# is actually a syntactic sugar for the
initobj instruction, which tells the CLR to zero out a given value type.
Unfortunatly the langage as it stands doesn't support any syntax to
initialize a variable to its default. Tthe C# 2.0 .default operator
should
give the behaviour the OP is looking for, if I understand him correctly, but
I havn't taken the time to verify it again in the spec preview so it
could
just be an artifact of the current build, but I don't think so.
Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Yes, that may be true -- but, given an arbitrary value type, how do I
programmatically retrieve the default value for that type? It can't just
be
0 bits, because for a string (for example) that won't work.

I'd have hoped that the boxed equivalent of the value type would have
a
constructor, but GetConstructor returns null.

John,

My question is, how can I retrieve the default value for a given type?

The default is all bits zeroed out, meaning 0 or 0.0 for numeric
types, false for bools and null for reference types.

For value types, you get the default value when using the default
constructor.

double d = new double(); // effectively the same as double d = 0.0;



Mattias
 
Ah! I hadn't considered trying CreateInstance. That works great, thanks!

Nicholas Paldino said:
John,

You actually don't need to get a constructor, you can just call the
version of CreateInstance that takes just the type, it will create an
instance with the bits zeroed out, like this:

// Get the type.
Type pobjIntType = typeof(int);

// Create an instance.
object pobjInt = Activator.CreateInstance(pobjIntType);

Of course, you only run this code if you have a value type, otherwise,
you just return null (for reference types). The full code I would use is:

public static object GetDefaultValue(Type type)
{
// If type is null, throw an exception.
if (type == null)
// Throw an exception.
throw new ArgumentNullException("type");

// Check to see if the type is a value type.
// If it is not, return null.
if (!type.IsValueType)
// Return null.
return null;

// Create an instance of the value type.
return Activator.CreateInstance(type);
}


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

John Wood said:
If you run GetConstructor on the value type it returns null though...
doesn't look like any of the value types can provide a default constructor.

message news:[email protected]...
John,

Yes, actually it would. With Guid and DateTime, since they are
structures, they have default constructors, which you can get through
reflection and call through reflection (once you have the type).

With a string, it is not a value type, so the default value for a string
is null, which the algorithm that I detailed in my previous post will return
to you.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Right, but that won't work for Guid, DateTime or String (to name a few).
Isn't there a method somewhere in the framework that just returns the
default value for a given type?

in
message John,

It's actually quite simple. You can use reflection to determine
whether
or not the type derives from ValueType in some way. If it does, then
you
can just use the default constructor to generate a value with the bits
zeroed out. If it does not derive from ValueType, then it is a
reference
type, and the default value is null.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Yes, that may be true -- but, given an arbitrary value type, how
do
I
programmatically retrieve the default value for that type? It can't
just
be
0 bits, because for a string (for example) that won't work.

I'd have hoped that the boxed equivalent of the value type would have
a
constructor, but GetConstructor returns null.

John,

My question is, how can I retrieve the default value for a given
type?

The default is all bits zeroed out, meaning 0 or 0.0 for numeric
types, false for bools and null for reference types.

For value types, you get the default value when using the default
constructor.

double d = new double(); // effectively the same as double d
=
0.0;
 
John Wood said:
Yes, that may be true -- but, given an arbitrary value type, how do I
programmatically retrieve the default value for that type? It can't just be
0 bits, because for a string (for example) that won't work.

String isn't a value type though - it's a reference type, so the
default value for a string variable is null.
 
John Wood said:
Even though CSC does its best to detect use of unassigned variables, it
often misses it...

No, it doesn't miss anything - you're simply allowed to use the default
value of instance/static members, whereas unassigned *local* variables
don't have any default value, and you can't use them until they're
definitely assigned.
 
Something I never fully understood. There's no difference as far as I see...
an unassigned local variable is just as ambiguous as an unassigned member
variable.
 
John Wood said:
Something I never fully understood. There's no difference as far as I see...
an unassigned local variable is just as ambiguous as an unassigned member
variable.

There's no ambiguity - it has a very specific default value, and the
time at which that value is assigned to it is well-specified.

The reason for making unassigned local variables an error but not
unassigned member variables is that the flow is much more guaranteed
through a method than uses of a class. For instance, take the
property/variable combo:

string name;
public string Name
{
get { return name; }
set { name = value; }
}

There's absolutely no guarantee what order things will be called in -
so there *has* to be a specification about what will happen if the
"getter" is called before the "setter". With a local variable, however,
you can almost always make sure that the first assignment is a useful
one, and that no "reads" occur before that time. It's only very
occasionally that you need to specify a dummy initial value because the
compiler can't tell that you'll actually always overwrite the initial
value with a "real" value before you read the variable for the first
time.

Would you prefer that every member variable had to have an explicit
assignment at declaration? Or that declaration of a local variable also
implicitly included an assignment even if one was not present?
 
Sure, there's no implicit order to the code that runs in a class, which is
what i meant by 'missing' it.

Either the variables get assigned a default value and therefore don't need
to be initialized, or they do need to be initialized... seems like it has it
both ways here.

If the compiler is capable of assigning a default value, then why shouldn't
the same logic apply to a class?

I think it makes sense to have a default value assigned to a value type, and
not require you to initialize in both cases -- after all it has one when
it's created anyway, forcing you to set it up to a different value after
it's been constructed is just a waste isn't it?
 
John Wood said:
Sure, there's no implicit order to the code that runs in a class, which is
what i meant by 'missing' it.

Either the variables get assigned a default value and therefore don't need
to be initialized, or they do need to be initialized... seems like it has it
both ways here.

Nope. The only difference is between local variables and member
variables. Reference types and value types all have default values. I
don't see what's "both ways" about it.
If the compiler is capable of assigning a default value, then why shouldn't
the same logic apply to a class?

Do you mean why isn't there a constructor called for reference types as
well? There's a perfectly good default value for reference types -
null. Bear in mind that not every class *has* a parameterless
constructor. If you're not talking about that, please explain what
you're after again.
I think it makes sense to have a default value assigned to a value type, and
not require you to initialize in both cases -- after all it has one when
it's created anyway, forcing you to set it up to a different value after
it's been constructed is just a waste isn't it?

If you're talking about local variables, they *aren't* logically
assigned a value until they're specifically assigned one. I'm still not
sure what change you're suggesting though - could you be more explicit?
 
Jon Skeet said:
If you're talking about local variables, they *aren't* logically
assigned a value until they're specifically assigned one. I'm still not
sure what change you're suggesting though - could you be more explicit?

I guess I wasn't being clear enough, sorry about that.

Thinking about it further, my opinion is that it actually makes sense to
explicitly initialize *all* value type variables, whether local or member
level. I like everything to be explicit, and I think this is more consistent
with the C# philosophy (where casting is also explicit, for example). For
member level, initialization could occur as part of the declaration, or in
the constructor(s).

I think the default null value for reference types makes sense and should be
implicit.

Do you disagree with that?
 
Back
Top