简体   繁体   中英

C# - Generic Types in Method Signature - Why CS1503, “Cannot Convert from IThing to ns.IThing”?

While trying to work out an adapter pattern for use in an EFCore application with C# 9 under Visual Studio 2019, I'd developed a method something like the HandleThing<IThing>(IThing otherThing) method, below

namespace ns {
  public interface IThing
    {

    }

    public class Thing : IThing
    {
        public Thing(IThing thing)
        {
        }
    }

    public class ThingHandler
    {
        public void HandleThing<IThing>(IThing otherThing)
        {
            var entityThing = new Thing(otherThing);
        }
}

Subsequently, I'm presented with an error in the HandleThing<IThing> definition, at the 'otherThing' argument to the Thing constructor: "CS1503: Argument 1: Cannot convert from 'IThing' to 'ns.IThing'".

While VS recommends a cast such as the following, and that appears to work out at this point, I'm not certain I understand why this error is occurring, or why the cast would be needed.


    public class ThingHandler
    {
        public void HandleThing<IThing>(IThing otherThing)
        {
            var entityThing = new Thing((ns.IThing)otherThing);
        }
    }

Updating it to the following, it also eliminates a warning about nullability


    public class ThingHandler
    {
        public void HandleThing<IThing>(IThing otherThing)
            where IThing: notnull
        {
            var entityThing = new Thing((ns.IThing)otherThing);
        }
    }

It was my impression that the IThing type in the initial HandleThing<IThing>(IThing otherThing) signature would represent the IThing interface type that I'd already declared.

Is something getting lost across the generics in the definition?

The problem is the generic parameter was unconstrained.

Your generic parameter declaration <IThing> was a little skewed (which was likely confusing). Use T , and then constrain by Ithing

What you had

public void HandleThing<IThing>(IThing otherThing)

Instead, use standard T or T prefix so you don't get confused

public class ThingHandler
{
   public void HandleThing<T>(T otherThing) where T : IThing
   {
      var entityThing = new Thing(otherThing);
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM