Перегрузка методов в C#. Почему нет конфликта выбора метода?
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 18.02.14 13:01
Оценка:
Исходная задача.

— Есть класс MyConnection, производный от DbConnection.
— В нем реализован виртуальный метод
public virtual DataTable GetSchema(string collectionName,string[] restrictionValues)

На днях осознал тупость этого метода и добавил новый метод с тем же (эксперимента ради) именем.
public virtual DataTable GetSchema(string collectionName,object[] restrictionValues)

Пересобрал тесты (VS2008 NET3.5, VS2010 NET4, VS2012 NET4.5). Никаких проблем и предупреждений.

Запустил отладку под VS2012 и обнаружил, что вызовы к GetSchema(...,string[]) переключились на GetSchema(...,object[]).

То есть:
static DataTable CallGetSchema(MyConnection cn,string name,string[] restrictionValues)
{
 //Раньше вызывал GetSchema(string collectionName,string[] restrictionValues)
 //Теперь вызывает GetSchema(string collectionName,object[] restrictionValues)
 return cn.GetSchema(name,restrionValues);
}//CallGetSchema

Собственно вопрос — а чего это компилятор выбрал метод с object[] вместо string[]?

-----
Решил по-изучать этот вопрос по-подробнее:

  Скрытый текст
using System;

namespace NS{
////////////////////////////////////////////////////////////////////////////////
//class TBase

abstract class TBase
{
 public abstract void Method1(string[] values);
};//class TBase

////////////////////////////////////////////////////////////////////////////////
//class TObj

class TObj:TBase
{
 public override void Method1(string[] values)
 {
  Console.WriteLine("Method1(string[])");
 }

 public void Method1(object[] values)
 {
  Console.WriteLine("Method1(object[])");
 }

 public void Method2(string[] values)
 {
  Console.WriteLine("Method2(string[])");
 }

 public void Method2(object[] values)
 {
  Console.WriteLine("Method2(object[])");
 }
};//class TObj

////////////////////////////////////////////////////////////////////////////////
//class Program

class Program
{
 static void Main(string[] args)
 {
  object[] data_objs=new object[]{"1","2"};
  string[] data_strs=new string[]{"1","2"};
  
  TObj  obj=new TObj();
  TBase basE=obj;

  Console.WriteLine("-------------- 1.");
  obj.Method1(data_strs);  //call of Method1(object[]); !!!
  obj.Method1(data_objs);  //call of Method1(object[]);

  Console.WriteLine("-------------- 2.");
  obj.Method1(null);  //call of Method1(object[]);

  Console.WriteLine("-------------- 3.");
  basE.Method1(data_strs);

  Console.WriteLine("-------------- 4.");
  obj.Method2(data_strs);  //call of Method1(string[]);
  obj.Method2(data_objs);  //call of Method1(object[]);

  Console.WriteLine("-------------- 5.");
  obj.Method2(null);  //call of Method1(string[]);

 }//Main
};//class Program

////////////////////////////////////////////////////////////////////////////////
}//namespace NS


Вывод:

-------------- 1.
Method1(object[])
Method1(object[])
-------------- 2.
Method1(object[])
-------------- 3.
Method1(string[])
-------------- 4.
Method2(string[])
Method2(object[])
-------------- 5.
Method2(string[])

Вопрос — это нормальное поведение, которое не будет объявлено "вне закона" в будущем?

Или лучше все таки перестраховаться и дать своему методу уникальное имя, типа GetSchemaEx(string,object[])?
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.