Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
174 views
in Technique[技术] by (71.8m points)

C#: Passing null to overloaded method - which method is called?

Say I have two overloaded versions of a C# method:

void Method( TypeA a ) { }
void Method( TypeB b ) { }

I call the method with:

Method( null );

Which overload of the method is called? What can I do to ensure that a particular overload is called?

question from:https://stackoverflow.com/questions/719546/c-passing-null-to-overloaded-method-which-method-is-called

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It depends on TypeA and TypeB.

  • If exactly one of them is applicable (e.g. there is no conversion from null to TypeB because it's a value type but TypeA is a reference type) then the call will be made to the applicable one.
  • Otherwise it depends on the relationship between TypeA and TypeB.
    • If there is an implicit conversion from TypeA to TypeB but no implicit conversion from TypeB to TypeA then the overload using TypeA will be used.
    • If there is an implicit conversion from TypeB to TypeA but no implicit conversion from TypeA to TypeB then the overload using TypeB will be used.
    • Otherwise, the call is ambiguous and will fail to compile.

See section 7.4.3.4 of the C# 3.0 spec for the detailed rules.

Here's an example of it not being ambiguous. Here TypeB derives from TypeA, which means there's an implicit conversion from TypeB to TypeA, but not vice versa. Thus the overload using TypeB is used:

using System;

class TypeA {}
class TypeB : TypeA {}

class Program
{
    static void Foo(TypeA x)
    {
        Console.WriteLine("Foo(TypeA)");
    }

    static void Foo(TypeB x)
    {
        Console.WriteLine("Foo(TypeB)");
    }

    static void Main()
    {
        Foo(null); // Prints Foo(TypeB)
    }
}

In general, even in the face of an otherwise-ambiguous call, to ensure that a particular overload is used, just cast:

Foo((TypeA) null);

or

Foo((TypeB) null);

Note that if this involves inheritance in the declaring classes (i.e. one class is overloading a method declared by its base class) you're into a whole other problem, and you need to cast the target of the method rather than the argument.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...