繁体   English   中英

C#泛型引用类型约束中的面向错误:“ T”不包含“ FooMethod”的定义

[英]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.

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