1

我有一长串方法重载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(dynamic)重载在技术上与 相同M(object),因此重载解析会一次又一次地选择动态重载......

我怎样才能防止这种情况?

4

2 回答 2

3

为了使调用者不需要做任何事情,最简单的方法将“要调用的公共方法”与“实现”分开:

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.
}
于 2013-04-17T15:30:24.447 回答
0

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

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
于 2013-04-17T15:26:39.720 回答