具有类实现接口的C#方法泛型
更新:这并不像我希望的那样有效,正如其他人在下面所说的,这不是一个真正有效的方法。将以另一种方式处理我需要的东西 我已经创建了一个接口,其中包含一个使用泛型参数的方法和一个实现它的类。但是在类实现中,我得到一个错误,即类没有实现类上的成员。这似乎很奇怪具有类实现接口的C#方法泛型,c#,.net,generics,interface,C#,.net,Generics,Interface,更新:这并不像我希望的那样有效,正如其他人在下面所说的,这不是一个真正有效的方法。将以另一种方式处理我需要的东西 我已经创建了一个接口,其中包含一个使用泛型参数的方法和一个实现它的类。但是在类实现中,我得到一个错误,即类没有实现类上的成员。这似乎很奇怪 interface InterfaceA { String MethodA<T>(T obj); } public class ClassA : InterfaceA { public String name { g
interface InterfaceA
{
String MethodA<T>(T obj);
}
public class ClassA : InterfaceA
{
public String name { get; set; }
public ClassA()
{
this.name = "My Name";
}
public String MethodA<ClassA>(ClassA aClass)
{
String result = aClass.name; //ERROR IS ON THIS LINE
return result;
}
}
public class ClassB : InterfaceA
{
public String test1 { get; set; }
public ClassB()
{
this.test1 = String.Empty;
}
public String MethodA<ClassB>(ClassB obj)
{
String result = obj.test1;
return result;
}
}
public class ClassC : InterfaceA
{
public String test2 { get; set; }
public ClassC()
{
this.test2 = String.Empty;
}
public String MethodA<ClassC>(ClassC obj)
{
String result = obj.test2;
return result;
}
}
接口a
{
字符串方法a(T-obj);
}
公共类A类:接口A
{
公共字符串名称{get;set;}
公共甲级()
{
this.name=“我的名字”;
}
公共字符串方法A(ClassA aClass)
{
String result=aClass.name;//此行有错误
返回结果;
}
}
公共类B类:接口A
{
公共字符串test1{get;set;}
公共类别B()
{
this.test1=String.Empty;
}
公共字符串方法A(ClassB obj)
{
字符串结果=obj.test1;
返回结果;
}
}
公共类C类:接口A
{
公共字符串test2{get;set;}
公共类别c()
{
this.test2=String.Empty;
}
公共字符串方法A(ClassC obj)
{
字符串结果=obj.test2;
返回结果;
}
}
这会导致“错误CS1061'ClassA'不包含'name'的定义,并且找不到接受'ClassA'类型的第一个参数的可访问扩展方法'name'(是否缺少using指令或程序集引用?)
我肯定我这里出了什么问题,但我不确定是什么问题。这个问题可能是由于您使用了
ClassA
名称作为泛型类型造成的。在本例中,这隐藏了ClassA
的真实定义。因此,使用另一个名称,在C#中使用T
。现在它可以是任何类型,但是如果您想确保它具有name
属性,那么您需要一个泛型类型约束。例如,这将起作用:
interface InterfaceA
{
string MethodA<T>(T obj) where T : ClassA;
//^^^^^^^^^^^^^^^^
}
public class ClassA : InterfaceA
{
public String name { get; set; }
public ClassA()
{
this.name = "My Name";
}
public string MethodA<T>(T aClass) where T : ClassA
//^^^^^^^^^^^^^^^^
{
String result = aClass.name;
return result;
}
}
现在,您的其他代码如下所示:
interface InterfaceA
{
string MethodA<T>(T obj) where T : INamed;
//^^^^^^^^^^^^^^^^
}
public class ClassA : InterfaceA, INamed
{
public String name { get; set; }
public ClassA()
{
this.name = "My Name";
}
public string MethodA<T>(T aClass) where T : INamed
//^^^^^^^^^^^^^^^^
{
String result = aClass.name;
return result;
}
}
接口a
{
字符串方法a(T obj),其中T:INamed;
//^^^^^^^^^^^^^^^^
}
公共类A类:接口A,未命名
{
公共字符串名称{get;set;}
公共甲级()
{
this.name=“我的名字”;
}
公共字符串方法A(T aClass),其中T:INamed
//^^^^^^^^^^^^^^^^
{
字符串结果=aClass.name;
返回结果;
}
}
忽略一个事实,即您知道ClassA
具有名称
属性
编译器看到MethodA
是InterfaceA
的成员(ClassA实现的接口)。该方法在类型T
中是通用的,其中T
没有约束。您正在使用ClassA
作为类型参数来实现MethodA
。你可以用任何类型的。当您调用aClass.name
getter时,编译器会说“嘿,T上没有约束,您不能使用它的任何成员”
要解决此问题,请添加如下界面:
public interface IHaveAName
{
string name {get;}
}
然后将接口定义更改为:
interface InterfaceA
{
String MethodA<T>(T obj) where T: IHaveAName;
}
你可能想重新思考一下你在做什么(我猜如果这不是一个没有意义的名字的模糊不清的例子,你这么做的原因会更明显)。鉴于您提供的信息,很难理解为什么要以这种方式构造对象。如果在给定的类中,您总是希望使用相同的参数类型调用方法,则 解决方案是将泛型类型参数添加到接口:
接口a
{
字符串方法a(T-obj);
}
然后你可以像这样实现它
公共类A类:接口A
{
公共字符串名称{get;set;}
公共甲级()
{
this.name=“我的名字”;
}
公共字符串方法A(ClassA aClass)
{
String result=aClass.name;//此处不再出现错误。
返回结果;
}
}
为什么MethodA
一开始甚至是通用的?如果你只想用一个ClassA
,那就这么做吧。因为这是一个简化的例子,在真实的例子中,我有十几个或更多的类实现了这个接口,并且该方法的参数需要采用不同的类型。@stuartd为什么编译器推断aClass
属于InterfaceA
类型?为什么statingMethodA
不指示编译器将aClass
视为ClassA
而是视为InterfaceA
?但是我需要接口是泛型的,而不是特定于类A。因此我还可以有:公共类ClassB:InterfaceA公共字符串方法A(ClassB obj),正如我在最后一句中所说的,将name
属性提取到它自己的接口中,并将其用作约束。对于使用该接口的每个类中的每个属性?类的属性不同,每个方法都使用类属性。它几乎像是要专门化泛型…ALA+ C++。但这不是c#中泛型的工作方式,我没有包括“为什么”,因为这不是我的问题,我不想写一本解释我在做什么的小说。我可以用另一种方式做我需要做的事情,只是如果这样做有效,这会更简单。这就是为什么我的问题是这能起作用吗?如果答案是否定的,很好。所以既然它似乎不是这样工作的,那么我就用我的另一种方法。@SoftwareNinja:我明白了。我很欣赏这个漂亮的小东西——如果每个人都能把一个问题浓缩得这么好就好了。我只是想指出,根据你提供的信息,我们没有什么可以说的了。这两个答案是相似的,并提供了解决方案的途径;虽然可能不是你想要的。
interface InterfaceA
{
String MethodA<T>(T obj) where T: IHaveAName;
}
public class ClassA : InterfaceA, IHaveAName