Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何为泛型类方法获取正确的扩展方法?_C#_Generics_Inheritance_Extension Methods - Fatal编程技术网

C# 如何为泛型类方法获取正确的扩展方法?

C# 如何为泛型类方法获取正确的扩展方法?,c#,generics,inheritance,extension-methods,C#,Generics,Inheritance,Extension Methods,我最近在编写代码时遇到了这个问题。是否有一种方法可以在基类中编写代码,以便它根据类型识别正确的扩展方法 namespace GenericsInheritance { public class Animal { } public class Dinasaur : Animal { } public class Dragon : Animal { } public abstract class Zoo<T> where T : Animal

我最近在编写代码时遇到了这个问题。是否有一种方法可以在基类中编写代码,以便它根据类型识别正确的扩展方法

namespace GenericsInheritance
{
    public class Animal { }

    public class Dinasaur : Animal { }

    public class Dragon : Animal { }

    public abstract class Zoo<T> where T : Animal
    {
        public virtual string IdentifyYourSelf(T record)
        {
            //Calling extension method
            string name = record.IdentifyYourSelf();
            return name;
        }
    }

    public class DinasaurZoo : Zoo<Dinasaur> 
    {
        //I could use this, just wanted to try if base class method does identify the correct extension method for the type.
        //public override string IdentifyYourSelf(Dinasaur record)
        //{
        //    return record.IdentifyYourSelf();
        //}
    }

    public class DragonZoo : Zoo<Dragon> { }

    public class AnimalZoo : Zoo<Animal> { }

    //Extensions methods class.
    public static class LieDetector
    {
        public static string IdentifyYourSelf(this Animal record) { return "Animal"; }

        public static string IdentifyYourSelf(this Dinasaur record) { return "Dinasaur"; }

        public static string IdentifyYourSelf(this Dragon dog) { return "Dragon"; }

        //It works if I use this.
        //public static string IdentifyYourSelf<T>(this T record) where T : Animal
        //{            
        //    if (record is Dinasaur) { var dinasaur = record as Dinasaur; return IdentifyYourSelf(dinasaur); }
        //    else if (record is Dragon) { var dragon = record as Dragon; return IdentifyYourSelf(dragon); }        
        //    else return "I do not exist";
        //}
    }

    public class FbiInterrogation
    {
        public static void Main(string[] args)
        {
            var animal = new Animal();
            var dinasaur = new Dinasaur();
            var dragon = new Dragon();
            var dinasaurZoo = new DinasaurZoo();
            var dragonZoo = new DragonZoo();
            var animalZoo = new AnimalZoo();

            string name = dinasaurZoo.IdentifyYourSelf(dinasaur); //Prints Animal expecting Dinasaur
            name = dragonZoo.IdentifyYourSelf(dragon); //Prints Animal expecting Dragon
            name = animalZoo.IdentifyYourSelf(animal); //Prints Animal

            Console.ReadKey();
        }
    }
}
命名空间泛型继承
{
公营动物{}
公营恐龙:动物{}
公共类龙:动物{}
公共抽象类动物园T:动物
{
公共虚拟字符串标识(T记录)
{
//调用扩展方法
string name=record.identificationyourself();
返回名称;
}
}
公共类恐龙动物园:动物园
{
//我可以使用它,只是想尝试一下基类方法是否为类型识别了正确的扩展方法。
//公共重写字符串IdentifyYourSelf(Dinasaur记录)
//{
//返回记录。identificationyourself();
//}
}
公立龙动物园:动物园{}
公营动物动物园:动物园{}
//扩展方法类。
公共静态类检测器
{
公共静态字符串IdentifyYourSelf(此动物记录){返回“动物”;}
公共静态字符串identificationYourself(此恐龙龙记录){返回“恐龙龙”;}
公共静态字符串识别您自己(此龙狗){返回“龙”;}
//如果我用这个就行了。
//公共静态字符串标识您自己(此T记录),其中T:Animal
//{            
//如果(记录为恐龙龙){var恐龙龙=记录为恐龙龙;返回identificationyourself(恐龙龙);}
//else if(记录为龙){var Dragon=记录为龙;返回identificationyourself(龙);}
//否则返回“我不存在”;
//}
}
公共类FBI交互
{
公共静态void Main(字符串[]args)
{
var动物=新动物();
var dinasaur=新的dinasaur();
var dragon=新龙();
var dinasaurZoo=新的dinasaurZoo();
var dragonZoo=新的dragonZoo();
var animalZoo=新的animalZoo();
string name=dinasaurZoo.identificationyourself(dinasaur);//打印动物
name=dragonZoo.IdentificationYourself(dragon);//打印动物期待龙
name=animalZoo.识别你自己(动物);//打印动物
Console.ReadKey();
}
}
}

扩展方法是根据调用它们的变量的静态类型而不是运行时类型来解析的。因此,您的问题的答案是“否”-您必须通过派生类中的重写或繁琐的类型检查来实现,正如您在问题中所指出的那样。

这实际上可以通过使用反射来实现,尽管我不确定这样做是否是最好的方法:

public abstract class Zoo<T> where T : Animal
{
    public virtual string IdentifyYourSelf(T record)
    {
        return typeof(LieDetector).GetMethod("IdentifyYourSelf", new[] {typeof(T)}, null).Invoke(record, new object[] {record}) as string;
    }
}
公共抽象类,其中T:Animal
{
公共虚拟字符串标识(T记录)
{
返回typeof(LieDetector).GetMethod(“identificationyourself”,new[]{typeof(T)},null).Invoke(record,newobject[]{record})作为字符串;
}
}

扩展方法是根据调用它们的变量的静态类型而不是运行时类型来解析的。因此,您的问题的答案是“否”——您必须通过派生类中的重载来执行。重载还是重写?@phoog:将其放入答案中,因为这就是答案。顺便说一句,它是超负荷的,而不是超负荷的。@StefanSteinegger感谢您的纠正和建议。