Search code examples
c#genericscastingc#-12.0

User-defined implicit cast to generic is not used


I have a class that encapsulates a generic class T, and it has an implicit operator to convert the encapsulating class to T.

However, that conversion is only ever used if I cast explicitly in the calling code. I haven't found any rules that seem to apply. This is .Net 8.0, C# 12.

internal class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello, World!");

        var r = new Result<Contact>(new Contact() { FullName = "Otto" });
        Console.WriteLine(r.Value.FullName); // This works, no surprise
        Console.WriteLine(r.FullName); // Squiggly under FullName. CS1061: 'Result<Contact>' does not contain a definition for 'FullName' and no accessible extension method... 
        Console.WriteLine(((Contact)r).FullName); // Explicit cast works
    }
}

public class Contact
{
    public string FullName { get; set; } = "";
}

public class Result<T>
{
    public T Value { get; }
    public int Index { get; }

    public Result(T value)
    {
        Value = value;
        Index = 0;
    }

    public Result(T value, int index)
    {
        Value = value;
        Index = index;
    }

    public static implicit operator T(Result<T> result)
    {
        return result.Value;
    }
}


Solution

  • A variable can only have one type. In your case r is Result<Contact>. You cannot use it as both Result<Contact and Contact for simultaneous access to members of both types.

    What you did allows you to pass r where Contact is expected without needing to explicitly cast.

    var r = new Result<Contact>(new Contact() { FullName = "Otto" });
    Console.WriteLine(r.Value.FullName); //Otto
    // implicit cast works because the parameter is of type Contact
    // which Result<Contact> impicitly converts to
    Action<Contact> action = c => Console.WriteLine(c.FullName);
    action(r); // Otto