我很难理解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"});
}
}
我不明白为什么编译器对我的接口实现不满意。如果我将参数存储在类变量中,那就更不高兴了:
class Device : ISetUp
{
private DeviceParameter param;
public void SetUp<DeviceParameter>(DeviceParameter parameter)
{
// Error here: Cannot implicitly convert type 'DeviceParameter' to 'ConsoleApp.DeviceParameter'
param = parameter;
}
}
当我在界面中将方法类型更改为类类型时,我可以很高兴地使用我的参数:
interface ISetUp<T>
{
void SetUp(T parameter);
}
我完全确定这是一个重复的问题,但是我找不到合适答案的链接。我只是想不理解泛型方法的概念。如果有人会为我指出正确的方向,我真的很感激。
答案 0 :(得分:3)
当您执行public void SetUp<DeviceParameter>(DeviceParameter parameter)
时,实际上定义了带有通用参数SetUp
的通用方法DeviceParameter
。此类型与您的课程无关。
因此,您只需要用第二个代码即可实现:
interface ISetUp<T>
{
void SetUp(T parameter);
}
如果您还有其他问题,我们很乐意为您解答:-)
答案 1 :(得分:1)
您将方法定义为通用方法,因此必须将其实现为通用方法。您可以将通用属性添加到Type而不是方法中:
interface ISetUp<T>
{
void SetUp(T parameter);
}
与实现此接口时相比,您可以指定通用属性:
class Device : ISetUp<DeviceParameter>
{
public void SetUp(DeviceParameter parameter)
{
Console.WriteLine(parameter.Param);
}
}
答案 2 :(得分:0)
SetUp<T>(T parameter)
表示让呼叫者决定他要使用什么参数。从理论上讲,我可以称呼mySetupClass.SetUp<string>("")
和mySetupClass.SetUp<int>(3)
通过用SetUp<DeviceParameter>
覆盖它,您确实隐藏了原始方法。
也许您想做的就是使您的界面通用,例如:ISetUp<T>
答案 3 :(得分:0)
此
SetUp<DeviceParameter>(DeviceParameter parameter)
看起来像是对您的DeviceDevice类的引用,但并非如此。 这完全等同于
SetUp<T>(T parameter)
我希望这可以解释为什么不知道T.Param或DeviceParameter.Param。
您应该拥有
class Device : ISetup<DeviceParameter>
和
public void SetUp(DeviceParameter parameter)
答案 4 :(得分:0)
我通过此实现更改了下面的代码,它可以正常工作。
通用类型参数允许您在编译时为方法指定任意类型T,而无需在方法或类声明中指定具体类型。
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);
}
}