Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.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# 专门化GenericType的实现<;A、 B>;对于情况A==B?_C#_Generics_Overloading - Fatal编程技术网

C# 专门化GenericType的实现<;A、 B>;对于情况A==B?

C# 专门化GenericType的实现<;A、 B>;对于情况A==B?,c#,generics,overloading,C#,Generics,Overloading,我有一个泛型类,它接受两个类型参数,generic。此类具有签名的方法非常长,并且A和B是不同的。但是,如果A==B签名完全匹配,则无法执行重载解析。是否有可能为这种情况指定专门的方法?或者强制编译器任意选择一个匹配的重载 using System; namespace Test { class Generic<A, B> { public string Method(A a, B b) { return a.

我有一个泛型类,它接受两个类型参数,
generic
。此类具有签名的方法非常长,并且
A
B
是不同的。但是,如果
A==B
签名完全匹配,则无法执行重载解析。是否有可能为这种情况指定专门的方法?或者强制编译器任意选择一个匹配的重载

using System;

namespace Test
{
    class Generic<A, B>
    {
        public string Method(A a, B b)
        {
            return a.ToString() + b.ToString();
        }

        public string Method(B b, A a)
        {
            return b.ToString() + a.ToString();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Generic<int, double> t1 = new Generic<int, double>();
            Console.WriteLine(t1.Method(1.23, 1));

            Generic<int, int> t2 = new Generic<int, int>();
// Following line gives:
//     The call is ambiguous between the following methods
//     or properties: 'Test.Generic<A,B>.Method(A, B)' and
//     'Test.Generic<A,B>.Method(B, A)'
            Console.WriteLine(t2.Method(1, 2));   
        }
    }
}
使用系统;
名称空间测试
{
类泛型
{
公共字符串方法(A,B)
{
返回a.ToString()+b.ToString();
}
公共字符串方法(B,A)
{
返回b.ToString()+a.ToString();
}
}
班级计划
{
静态void Main(字符串[]参数)
{
泛型t1=新泛型();
控制台写入线(t1方法(1.23,1));
泛型t2=新泛型();
//下一行给出:
//以下方法之间的调用不明确
//或属性:“Test.Generic.Method(A,B)”和
//'测试通用方法(B,A)'
控制台写入线(t2方法(1,2));
}
}
}

如果您想让编译器任意决定事情,那么调用该方法的目的是什么?


如果您想让编译器任意决定事情,那么调用该方法的目的是什么?

鉴于纯粹的泛型定义,没有办法强制编译器选择重载。这两种方法无法区分胜利者

选择其中一个似乎是个好主意,但决策必须是确定性的。即使像文件中的第一个一样简单的东西也不可行,因为你必须考虑部分类。如果每个方法位于不同的文件中,编译器将如何选择第一个方法

不过,您可以添加一个接受int的方法的非泛型版本。编译器将选择非泛型版本而不是泛型版本,并且它将在这个非常有限的场景中产生胜利。但是,对于可能存在冲突的每种类型,您都必须重复这一点

比如说。添加此方法将解决编译错误,但仅适用于int

public string Method(int b, int a)
{
    return b.ToString() + a.ToString();
}

给定纯泛型定义,没有办法强制编译器选择重载。这两种方法无法区分胜利者

选择其中一个似乎是个好主意,但决策必须是确定性的。即使像文件中的第一个一样简单的东西也不可行,因为你必须考虑部分类。如果每个方法位于不同的文件中,编译器将如何选择第一个方法

不过,您可以添加一个接受int的方法的非泛型版本。编译器将选择非泛型版本而不是泛型版本,并且它将在这个非常有限的场景中产生胜利。但是,对于可能存在冲突的每种类型,您都必须重复这一点

比如说。添加此方法将解决编译错误,但仅适用于int

public string Method(int b, int a)
{
    return b.ToString() + a.ToString();
}

我知道这有点违背了泛型的目的,但是如果只定义一次方法,使用两个类型为
object
的参数,该怎么办

在方法内部,您可以检查类型并确定要调用两个选项中的哪一个

namespace Test
{
    class Generic<A, B>
    {
        public string Method(object a, object b)
        {
            if (a is A && b is B)
                return MethodOneTwo;
            else if (a is B && b is A)
                return MethodTwoOne;
            else
                throw new ArgumentException("Invalid Types");
        }

        private string MethodOneTwo(A a, B b)
        {
            return a.ToString() + b.ToString();
        }

        private string MethodTwoOne(B b, A a)
        {
            return b.ToString() + a.ToString();
        }
    }
}
名称空间测试
{
类泛型
{
公共字符串方法(对象a、对象b)
{
如果(a是a&&b是b)
返回方法二;
else if(a是B&&B是a)
返回方法二1;
其他的
抛出新ArgumentException(“无效类型”);
}
私有字符串方法二(A,B)
{
返回a.ToString()+b.ToString();
}
私有字符串方法二通(B,A)
{
返回b.ToString()+a.ToString();
}
}
}

我知道这有点违背了泛型的目的,但是如果只定义一次方法,使用两个类型为
object
的参数,该怎么办

在方法内部,您可以检查类型并确定要调用两个选项中的哪一个

namespace Test
{
    class Generic<A, B>
    {
        public string Method(object a, object b)
        {
            if (a is A && b is B)
                return MethodOneTwo;
            else if (a is B && b is A)
                return MethodTwoOne;
            else
                throw new ArgumentException("Invalid Types");
        }

        private string MethodOneTwo(A a, B b)
        {
            return a.ToString() + b.ToString();
        }

        private string MethodTwoOne(B b, A a)
        {
            return b.ToString() + a.ToString();
        }
    }
}
名称空间测试
{
类泛型
{
公共字符串方法(对象a、对象b)
{
如果(a是a&&b是b)
返回方法二;
else if(a是B&&B是a)
返回方法二1;
其他的
抛出新ArgumentException(“无效类型”);
}
私有字符串方法二(A,B)
{
返回a.ToString()+b.ToString();
}
私有字符串方法二通(B,A)
{
返回b.ToString()+a.ToString();
}
}
}

这将使用反射来获取方法并任意调用一个。您可以通过过滤参数和返回类型使其更加健壮,无论何时获得这些方法,都需要这些参数和返回类型

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    using System;
    using System.Reflection;

    namespace Test
    {
        class Generic<A, B>
        {
            public string Method(A a, B b)
            {
                return a.ToString() + b.ToString();
            }

            public string Method(B b, A a)
            {
                return b.ToString() + a.ToString();
            }
        }

        class Program
        {
            static void Main(string[] args)
            {
                Generic<int, double> t1 = new Generic<int, double>();
                Console.WriteLine(t1.Method(1.23, 1));

                Generic<int, int> t2 = new Generic<int, int>();
                // Following line gives:
                //     The call is ambiguous between the following methods
                //     or properties: 'Test.Generic<A,B>.Method(A, B)' and
                //     'Test.Generic<A,B>.Method(B, A)'
               MethodInfo [] methods = t2.GetType().GetMethods();
                foreach(MethodInfo method in methods)
                {
                    if (method.Name == "Method")
                    {
                        method.Invoke(t2,new Object[2] {1,2});
                        break;
                    }
                }
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统文本;
命名空间控制台应用程序1
{
使用制度;
运用系统反思;
名称空间测试
{
类泛型


我们真正需要的是在预编译或编译时生成具体签名的模板。

这将使用反射来获取方法并任意调用一个方法。您可以通过过滤参数和返回类型使其更加健壮,无论何时获取方法都是如此

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    using System;
    using System.Reflection;

    namespace Test
    {
        class Generic<A, B>
        {
            public string Method(A a, B b)
            {
                return a.ToString() + b.ToString();
            }

            public string Method(B b, A a)
            {
                return b.ToString() + a.ToString();
            }
        }

        class Program
        {
            static void Main(string[] args)
            {
                Generic<int, double> t1 = new Generic<int, double>();
                Console.WriteLine(t1.Method(1.23, 1));

                Generic<int, int> t2 = new Generic<int, int>();
                // Following line gives:
                //     The call is ambiguous between the following methods
                //     or properties: 'Test.Generic<A,B>.Method(A, B)' and
                //     'Test.Generic<A,B>.Method(B, A)'
               MethodInfo [] methods = t2.GetType().GetMethods();
                foreach(MethodInfo method in methods)
                {
                    if (method.Name == "Method")
                    {
                        method.Invoke(t2,new Object[2] {1,2});
                        break;
                    }
                }
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统文本;
命名空间控制台应用程序1
{
使用制度;
运用系统反思;
名称空间测试
{
类泛型

我们真正需要的是在预编译或编译时生成具体签名的模板