[英]Facing error in C# Generics Reference type constraint:'T' does not contain a definition for 'FooMethod'
public class Foo {
public Foo ThisX { get; set; }
public Foo ThisY { get; set; }
public Foo() {
}
public Foo(Foo x, Foo y) {
ThisX = x;
ThisY = y;
}
public void FooMethod(Foo ob) {
Console.WriteLine("Hiiiii\t" + ob);
}
}
public class Gen<T> where T : class {
T obj;
public Gen() {
}
public Gen(T x,T y) {
Console.WriteLine("Gen(T x,T y)\t" + x.GetType().Name + " " + y.GetType().Name);// + " " + obj.GetType().Name);
}
public void Display(T ob) {
obj = ob;
Console.WriteLine("Display " + ob.GetType().Name + " " + obj.GetType().Name);
obj.FooMethod(obj);
}
}
public class Program {
public static void Main(string[] args) {
Gen<Foo> m = new Gen<Foo>();
Foo ob1 = new Foo();
Foo ob2 = new Foo();
Console.WriteLine("Main " + m.GetType());
Console.WriteLine("Main " + ob1.GetType());
Console.WriteLine();
Gen<Foo> n = new Gen<Foo>(ob1, ob2);
Console.WriteLine();
m.Display(ob1);
}
}
行“ obj.FooMethod(obj)
”给出错误,指出“'T'不包含'FooMethod'的定义,并且找不到扩展方法'FooMethod'接受类型为'T'的第一个参数(您是否丢失了?使用指令或程序集引用?)”
您的答案是您在Gen中给出的类型约束
public class Gen<T> where T:class
此时,您将告诉编译器T 至少是至少一个类。 它可能会做更多,但如果绝对不会做得少。 在您的定义中,您要告诉编译器T至少是一个类。 类是任何人都可以创建的通用事物,它可以执行任何操作,但是至少它什么也不做。 编译器理解后面的内容,并假定最起码的最小值是一个空类,因为它不能保证总是有方法,属性,字段等。
为了使它起作用,我们需要帮助编译器了解我们要处理的内容。 T的实现具有一个通用定义FooMethod。 FooMethod内部会发生什么? 我们不在乎,Gen不在乎,我们只想执行它。 需要发生的是为Gen引入一个抽象基类或接口,以将其用作T的约束,这样我们至少已定义了此方法。 之后,我们将实现此抽象基类(或接口),以便编译器理解我们已定义了FooMethod。
最终代码如下:
//abstract class to establish the presence of FooMethod, but not the functionality
public abstract class FooBase {
public abstract void FooMethod(FooBase obj);
}
//Implement FooBase so that Foo is guaranteed to have a FooMethod implementation
public class Foo : FooBase
{
public Foo()
{
}
public Foo(Foo x, Foo y)
{
ThisX = x;
ThisY = y;
}
public Foo ThisX { get; set; }
public Foo ThisY { get; set; }
//Override FooMethod so that it can do whatever Foo needs it to do
public override void FooMethod(FooBase ob)
{
Console.WriteLine("Hiiiii\t" + ob);
}
}
public class Gen<T> where T : FooBase
{
T obj;
public Gen()
{
}
public Gen(T x, T y)
{
Console.WriteLine("Gen(T x,T y)\t" + x.GetType().Name.ToString() + " " + y.GetType().Name.ToString());//+" "+obj.GetType().Name.ToString());
}
public void Display(T ob)
{
obj = ob;
Console.WriteLine("Display " + ob.GetType().Name.ToString() + " " + obj.GetType().Name.ToString());
//Fire the objests implementation of FooBase.FooMethod(FooBase obj)
obj.FooMethod(obj);
}
}
public class Program
{
public static void Main(string[] args)
{
Gen<Foo> m = new Gen<Foo>();
Foo ob1 = new Foo();
Foo ob2 = new Foo();
Console.WriteLine("Main " + m.GetType());
Console.WriteLine("Main " + ob1.GetType());
Console.WriteLine();
Gen<Foo> n = new Gen<Foo>(ob1, ob2);
Console.WriteLine();
m.Display(ob1);
//To stop the console
Console.ReadLine();
}
}
您遇到的问题是方法FooMethod不是类的已知方法,因此通用Gen类试图在任何类中调用FooMethod并失败。 为了避免这种情况发生,在将军T类有自己等同于obj.FooMethod(OBJ)的签名; 从Gen叫来的
您可以通过2种方法来完成此工作,具体取决于要达到的目标。 如果Foo类是基类,则Gen类的声明使用基类而不是类,因此:
public class Gen<T> where T:Foo
{
}
或为Foo实施以下接口:
public interface IFoo<T>
{
public void FooMethod(T ob)
{
}
}
class Foo : IFoo<Foo>
{
}
并告诉您的Gen类仅使用实现该接口的类:
public class Gen<T> where T:IFoo
{
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.