Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.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# 提供动态过载时的StackOverflowException_C#_Dynamic_Overloading_Stack Overflow - Fatal编程技术网

C# 提供动态过载时的StackOverflowException

C# 提供动态过载时的StackOverflowException,c#,dynamic,overloading,stack-overflow,C#,Dynamic,Overloading,Stack Overflow,我有一长串方法重载M(…),我想提供一个通用方法M(object),它将根据对象的类型调用正确的重载。就在我编写一个用于调用正确重载的大型if语句之前,我意识到C#4具有dynamic关键字。所以我写了这个: class X { public void M(int x) { Console.WriteLine("M(int)"); } public void M(long x) { Console.WriteLine("M(long)"); } //

我有一长串方法重载
M(…)
,我想提供一个通用方法
M(object)
,它将根据对象的类型调用正确的重载。就在我编写一个用于调用正确重载的大型if语句之前,我意识到C#4具有
dynamic
关键字。所以我写了这个:

class X
{
    public void M(int x)
    { Console.WriteLine("M(int)"); }

    public void M(long x)
    { Console.WriteLine("M(long)"); }

    // ...20 more overloads of M() here...

    // For if you have an object of an unknown type:
    public void M(dynamic x)
    { M(x); }
}
当我正确使用它时,一切都很好。但是,当我提供错误类型的值时,动态重载解析(显然)递归到
M(dynamic)
,然后重试,导致无限递归,最终导致
StackOverflowException

X x = new X();
x.M((int)10);               // "M(int)"
x.M((long)10);              // "M(long)"
x.M((object)10);            // "M(int)"
x.M((object)String.Empty);  // StackOverflowException
当然,
M(动态)
重载在技术上与
M(对象)
相同,因此重载解析将一次又一次地拾取动态重载


如何防止这种情况发生?

我意识到不应该提供
M(动态)
重载。为了获得相同的行为,让调用方动态调用该方法。像这样:

X x = new X();
x.M((int)10);               // "M(int)"
x.M((long)10);              // "M(long)"
x.M((dynamic)10);           // "M(int)"
x.M((dynamic)String.Empty); // RuntimeBinderException

最简单的方法是将“要调用的公共方法”与“实现”分开,这样调用方就不需要做任何事情:


请注意,在C#4中引入了动态。您的意思是,对于每个
M(…)
方法,都有一个对应的私有
MImpl(…)
方法,然后让DLR在
MImpl
上执行重载解析,而不是
M
?@Virtlink:No,您只有一个M方法,它可以动态地分派给任意数量的MImpl方法。静态类型重载比动态类型重载快得多,并且为用户提供了有用的提示,因此在大多数情况下,我只想使用静态类型。否则,我显然不会公开其他重载。@Virtlink:在这种情况下,您可以提供
M
重载,它只委托给
MImpl
重载。那肯定有用。。。但老实说,你的要求并不明确。(特别是当你把表现带进来的时候,当你的问题中没有提到的时候。)
public void M(dynamic x)
{
    MImpl(x);
}

private void MImpl(int x)
{
    Console.WriteLine("M(int)");
}

// etc

private void MImpl(object x)
{
    // No more specific overloads matched. Throw some appropriate exception,
    // or take a default action.
}