Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7033375
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T01:03:30+00:00 2026-05-28T01:03:30+00:00

A while back I compiled two versions of a code, one using (Nullable<T>)x.GetValueOrDefault(y) and

  • 0

A while back I compiled two versions of a code, one using (Nullable<T>)x.GetValueOrDefault(y) and one using (Nullable<T>)x ?? y).

After decompiling to IL I noticed that the null coalesce operator is transformed into the GetValueOrDefault call.

Since it’s a method call to which an expression can be passed that is evaluated before execution of the method, y seems to be always executed.

For example:

using System;

public static class TestClass
{
    private class SomeDisposable : IDisposable
    {
        public SomeDisposable()
        {
            // Allocate some native resources
        }

        private void finalize()
        {
            // Free those resources
        }

        ~SomeDisposable()
        {
            finalize();
        }

        public void Dispose()
        {
            finalize();
            GC.SuppressFinalize(this);
        }
    }

    private struct TestStruct
    {
        public readonly SomeDisposable _someDisposable;
        private readonly int _weirdNumber;

        public TestStruct(int weirdNumber)
        {
            _weirdNumber = weirdNumber;
            _someDisposable = new SomeDisposable();
        }
    }

    public static void Main()
    {
        TestStruct? local = new TestStruct(0);

        TestStruct local2 = local ?? new TestStruct(1);

        local2._someDisposable.Dispose();
    }
}

Seems to result into an indisposed object, and probably performance implications too.

First of all, is this true? Or does the JIT or something alike change the actually executed ASM code?

And secondly can someone explain why it has this behavior?

NOTE: This is just an example, it is not based upon real code, and please refrain from making comments like ‘this is bad code’.

IL DASM:
Okay, when I compiled this with .Net Framework 2.0 it resulted in identical code with calling null coalesce and GetValueOrDefault. With .Net Framework 4.0, it generates these two codes:

GetValueOrDefault:

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       19 (0x13)
  .maxstack  2
  .locals init ([0] valuetype [mscorlib]System.Nullable`1<int32> nullableInt,
           [1] int32 nonNullableInt)
  IL_0000:  nop
  IL_0001:  ldloca.s   nullableInt
  IL_0003:  initobj    valuetype [mscorlib]System.Nullable`1<int32>
  IL_0009:  ldloca.s   nullableInt
  IL_000b:  ldc.i4.1
  IL_000c:  call       instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault(!0)
  IL_0011:  stloc.1
  IL_0012:  ret
} // end of method Program::Main

Null Coalesce:

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       32 (0x20)
  .maxstack  2
  .locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0,
           int32 V_1,
           valuetype [mscorlib]System.Nullable`1<int32> V_2)
  IL_0000:  nop
  IL_0001:  ldloca.s   V_0
  IL_0003:  initobj    valuetype [mscorlib]System.Nullable`1<int32>
  IL_0009:  ldloc.0
  IL_000a:  stloc.2
  IL_000b:  ldloca.s   V_2
  IL_000d:  call       instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
  IL_0012:  brtrue.s   IL_0017
  IL_0014:  ldc.i4.1
  IL_0015:  br.s       IL_001e
  IL_0017:  ldloca.s   V_2
  IL_0019:  call       instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
  IL_001e:  stloc.1
  IL_001f:  ret
} // end of method Program::Main

As it turns out that this is no longer the case, and that it skips over the GetValueOrDefault call altogether when HasValue returns false.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T01:03:31+00:00Added an answer on May 28, 2026 at 1:03 am

    After decompiling to IL I noticed that the null coalesce operator is transformed into the GetValueOrDefault call.

    x ?? y is transformed into x.HasValue ? x.GetValueOrDefault() : y. It is not transformed into x.GetValueOrDefault(y), and it would be a compiler bug if it were. You’re right, y should not be evaluated if x is not null, and it isn’t.

    Edit: If the evaluation of y can be proved free of side effects (where “side effect” includes “throws an exception”), then a transformation to x.GetValueOrDefault(y) wouldn’t necessarily be wrong, but it’s still a transformation that I don’t think the compiler performs: there aren’t all that many situations where that optimisation would be useful.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

A while back I created a lightbox plugin using jQuery that would load a
I noticed a good while back that Wikipedia links to a Javascript implementation of
A while back I was reading the W3C article on ' Re-using Strings in
A while back a found a great-looking framework that allowed .net developers to implement
I have run into a problem while writing C++ code that needs to compile
Consider the following code, compiled with g++ problem.cpp -o problem : #include <vector> using
While downloading Google Guice I noticed two main types of artifacts available on their
a while back I ran across a situation where we needed to display message-boxes
A while back I was trying to bruteforce a remote control which sent a
A while back i read somewhere about how to improve upon the MVC pattern

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.