简体   繁体   English

泛型方法无法推断类型

[英]Generic method cannot infer type

I'm having trouble to understand why the c# compiler is in trouble compiling the following example:我无法理解为什么 c# 编译器在编译以下示例时遇到问题:

    interface ISetUp
    {
        void SetUp<T>(T parameter);
    }

    class DeviceParameter 
    {
        public string Param { get; set; }
    }

    // implementation of ISetUp
    class Device : ISetUp
    {
        // Generates a warning here: 'Type parameter DeviceParameter hides class DeviceParameter'
        public void SetUp<DeviceParameter>(DeviceParameter parameter)
        {
            /* Terrible error here: 
            * 'DeviceParameter' does not contain a definition for 'Param' and no 
            * accessible extension method 'Param' accepting a first argument of type 
            * 'DeviceParameter' could be found (are you missing a using directive 
            * or an assembly reference?)  
            */
            Console.WriteLine(parameter.Param);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var device = new Device();
            device.SetUp(new DeviceParameter { Param = "Com1"});
        }
    }

I cannot understand why the compiler is unhappy with my implementation of the interface.我不明白为什么编译器对我的接口实现不满意。 If I was to store the parameter in a class variable, it's even more unhappy:如果我要将参数存储在 class 变量中,那就更不高兴了:

    class Device : ISetUp
    {
        private DeviceParameter param;
        public void SetUp<DeviceParameter>(DeviceParameter parameter)
        {
            // Error here: Cannot implicitly convert type 'DeviceParameter' to 'ConsoleApp.DeviceParameter'
            param = parameter;
        }
    }

When I change in my interface the method type to a class type I can cheerful use my parameter:当我在界面中将方法类型更改为 class 类型时,我可以愉快地使用我的参数:

    interface ISetUp<T>
    {
        void SetUp(T parameter);
    }

I'm totally sure this is a duplicate question, but I fail to find a link to an appropriate answer.我完全确定这是一个重复的问题,但我找不到合适答案的链接。 I just seam to not understand the concept of generic methods.我只是想不明白泛型方法的概念。 If someone would be kind to point me into the right direction, I really appreciate it.如果有人愿意为我指出正确的方向,我真的很感激。

When you do public void SetUp<DeviceParameter>(DeviceParameter parameter) you actually define a generic method SetUp with generic parameter DeviceParameter .当您执行public void SetUp<DeviceParameter>(DeviceParameter parameter)时,您实际上定义了一个通用方法SetUp与通用参数DeviceParameter This type has nothing to do with your class.此类型与您的 class 无关。 So what you want, you can only achieve with your second code:所以你想要什么,你只能用你的第二个代码来实现:

    interface ISetUp<T>
    {
        void SetUp(T parameter);
    }

If you have more questions, I'll be happy to answer them:-)如果您有更多问题,我很乐意为您解答:-)

You define method as generic so you must implement it as generic.您将方法定义为泛型,因此您必须将其实现为泛型。 You could add generic attribute to Type instead of method:您可以将通用属性添加到 Type 而不是方法:

interface ISetUp<T>
{
    void SetUp(T parameter);
}

than when you implement this interface you specify generic attribuite:与实现此接口相比,您指定通用属性:

class Device : ISetUp<DeviceParameter>
{
    public void SetUp(DeviceParameter parameter)
    {
        Console.WriteLine(parameter.Param);
    }
}

SetUp<T>(T parameter) means you let the caller decide what parameter he wants to use. SetUp<T>(T parameter)意味着你让调用者决定他想使用什么参数。 I could theoretically call both mySetupClass.SetUp<string>("") and mySetupClass.SetUp<int>(3)我理论上可以同时调用mySetupClass.SetUp<string>("")mySetupClass.SetUp<int>(3)

By overriding it with SetUp<DeviceParameter> you are indeed hiding the original method.通过用SetUp<DeviceParameter>覆盖它,您确实隐藏了原始方法。

Maybe what you wanted to do is make your interface generic, like: ISetUp<T>也许您想要做的是使您的界面通用,例如: ISetUp<T>

This这个

 SetUp<DeviceParameter>(DeviceParameter parameter)

Looks like a reference to your class DeviceParameter, but it isn't.看起来像是对您的 class 设备参数的引用,但事实并非如此。 This is completly equivalent to这完全等同于

 SetUp<T>(T parameter)

I hope this explains, why T.Param or DeviceParameter.Param is not known..我希望这能解释为什么不知道 T.Param 或 DeviceParameter.Param ..

You should have你应该有

class Device : ISetup<DeviceParameter>

and

public void SetUp(DeviceParameter parameter)

I changed the below part of code with this implementation, it works.我用这个实现改变了下面的代码部分,它可以工作。

A generic type parameter allows you to specify an arbitrary type T to a method at compile-time, without specifying a concrete type in the method or class declaration.泛型类型参数允许您在编译时为方法指定任意类型 T,而无需在方法或 class 声明中指定具体类型。

    public class Device : ISetUp
    {
        // Generates a warning here: 'Type parameter DeviceParameter hides class DeviceParameter'

        public void SetUp<T>(T parameter)
        {
            DeviceParameter dd = parameter as DeviceParameter;
            Console.WriteLine(dd.Param);

        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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