'Why (T) explicit cast not work in a <T>function

I want to use N<T> instead of use T? But I can't use(T) explicit cast in a function with<T>

Why (T) explicit cast not work? how to fix it.

Why (1 is int?) == true. How could I make my struct N has the same power. Make (1 is N <int> ) == true

using System;
public struct N<T> where T : struct
{
    public T value;
    public bool HasValue;
    public static implicit operator N<T>(T value)=> new N<T> { value = value };
    public static explicit operator T(N<T> value)=> value.value;
}

class Program
{
    static void Main(string[] args)
    {
        N<int> a;
        //System.Int32 can't cast to N`1[System.Int32]
        //error or not work
        a = To<N<int>>(2);

        //success     but not elegance
        a = To<N<int>>((N<int>)2);
        
        //success
        int? b = To<int?>(2);
        
        Console.ReadKey();
    }

    public static T To<T>( object o) 
    {
        //return (T)o;         //System.InvalidCastException
        if (o is T) 
        {
            Console.WriteLine("success");
            return (T)o; 
        }
        if (o is Func<T>)        {            return (o as Func<T>).Invoke();        }
        
        Console.WriteLine(o.GetType() + " can't cast to " + typeof(T));
        return default;
    }
}



Solution 1:[1]

A cast can mean a bunch of different things:

  • identity-preserving cast (upcast, downcast, interface cast)
  • boxing/unboxing
  • numeric conversion
  • call to user-defined conversion operator

Every time the compiler sees cast syntax, it has to look at the type to figure out which one. With generics, the compiler has only the generic constraints to use to decide which one.

To<T> has no constraints, so the compiler has to interpret the cast in a way that works with all types... every type inherits from object, so it chooses the cast from object to be a downcast. When you actually call the function, the input is a "boxed int* and the output type is N<int> and the downcast fails.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ben Voigt