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 7810749
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 2, 20262026-06-02T03:54:15+00:00 2026-06-02T03:54:15+00:00

I encountered some interesting behavior in the interaction between Nullable and implicit conversions. I

  • 0

I encountered some interesting behavior in the interaction between Nullable and implicit conversions. I found that providing an implicit conversion for a reference type from a value type it permits the Nullable type to be passed to a function requiring the reference type when I instead expect a compilation error. The below code demonstrates this:

static void Main(string[] args)
{
    PrintCatAge(new Cat(13));
    PrintCatAge(12);
    int? cat = null;
    PrintCatAge(cat);
}

private static void PrintCatAge(Cat cat)
{
    if (cat == null)
        System.Console.WriteLine("What cat?");
    else
        System.Console.WriteLine("The cat's age is {0} years", cat.Age);
}

class Cat
{
    public int Age { get; set; }
    public Cat(int age)
    {
        Age = age;
    }

    public static implicit operator Cat(int i)
    {
        System.Console.WriteLine("Implicit conversion from " + i);
        return new Cat(i);
    }
}

Output:

The cat's age is 13 years
Implicit conversion from 12
The cat's age is 12 years
What cat?

If the conversion code is removed from Cat then you get the expected errors:


Error 3 The best overloaded method match for 'ConsoleApplication2.Program.PrintCatAge(ConsoleApplication2.Program.Cat)' has some invalid arguments


Error 4 Argument 1: cannot convert from 'int?' to 'ConsoleApplication2.Program.Cat

If you open the executable with ILSpy the code that was generated is as follows

int? num = null;
Program.PrintCatAge(num.HasValue ? num.GetValueOrDefault() : null);

In a similar experiment I removed the conversion and added an overload to PrintCatAge that takes an int (not nullable) to see if the compiler would perform a similar operation, but it does not.

I understand what is happening, but I don’t understand the justification for it. This behavior is unexpected to me and seems odd. I did not have any success finding any reference to this behavior on MSDN in the documentation for conversions or Nullable<T>.

The question I pose then is, is this intentional and is there a explanation why this is happening?

  • 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-06-02T03:54:17+00:00Added an answer on June 2, 2026 at 3:54 am

    I said earlier that (1) this is a compiler bug and (2) it is a new one. The first statement was accurate; the second was me getting confused in my haste to get to the bus on time. (The bug I was thinking of that is new to me is a much more complicated bug involving lifted conversions and lifted increment operators.)

    This is a known compiler bug of long standing. Jon Skeet first brought it to my attention some time ago and I believe there’s a StackOverflow question about it somewhere; I do not recall where offhand. Perhaps Jon does.

    So, the bug. Let’s define a “lifted” operator. If an operator converts from a non-nullable value type S to a non-nullable value type T then there is also a “lifted” operator that converts from S? to T?, such that a null S? converts to a null T? and a non-null S? converts to T? by unwrapping S? to S, converting S to T, and wrapping T to T?.

    The specification says that (1) the only situation in which there is a lifted operator is when S and T are both non-nullable value types, and (2) that the lifted and non-lifted conversion operators are both considered as to whether they are applicable candidates for the conversion and if both applicable, then the source and target types of the applicable conversions, lifted or unlifted, are used to determine the best source type, best target type, and ultimately, best conversion of all the applicable conversions.

    Unfortunately, the implementation thoroughly violates all of these rules, and does so in a way that we cannot change without breaking many existing programs.

    First off, we violate the rule about the existence of lifted operators. A lifted operator is considered by the implementation to exist if S and T are both non-nullable value types, or if S is a non-nullable value type and T is any type to which a null could be assigned: reference type, nullable value type, or pointer type. In all those cases we produce a lifted operator.

    In your particular case, we lift to nullable by saying that we convert a nullable type to the reference type Cat by checking for null. If the source is not null then we convert normally; if it is, then we produce a null Cat.

    Second, we violate thoroughly the rule about how to determine the best source and target types of applicable candidates when one of those candidates is a lifted operator, and we also violate the rules about determining which is the best operator.

    In short, it is a big mess that cannot be fixed without breaking real customers, and so we will likely enshrine the behaviour in Roslyn. I will consider documenting the exact behaviour of the compiler in my blog at some point, but I would not hold my breath while waiting for that day if I were you.

    And of course, many apologies for the errors.

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

Sidebar

Related Questions

I encountered some strange behavior which hints that I do not understand some basic
I've encountered some code that's new to me... I've never really seen a type
I encountered some curious behavior today and was wondering if it is expected or
Trying to get comfortable with jQuery and I have encountered some sample code that
I've encountered lately some opinions saying that Object Oriented design/programming should not always be
I encountered a problem when running some old code that was handed down to
I encountered some peculiar difference in behavior of XSLT processors. I wonder what is
I recently encountered some code that gcc would not compile without this arg. I
Today I encountered interesting issue. That's what I have: 2 images with humanoids on
I've encountered some problems with MongoID. I have three models: require 'mongoid' class Configuration

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.