2015-12-14 3 views
3

В C#, если у меня естьЯвляется ли метод перегрузки полиморфизмом Раннее связывание в C#?

public class BaseClass 
{ 
    //BaseClass implementation 
} 

public class Derived : BaseClass 
{ 
    //Derived implementation 
} 

public class AnotherClass 
{ 
    AnotherClass(BaseClass baseClass) 
    { 
     //Some code 
    } 

    AnotherClass(Derived derived) : this(derived as BaseClass) 
    { 
     //Some more code 
    } 
} 

, а затем сделать:

BaseClass baseVariable = new Derived(); 
AnotherClass anotherVariable = new AnotherClass(baseVariable); 

Это приведет к раннему связыванию, вызывая метод AnotherClass(BaseClass).

Вместо этого, если я бросил его, используя dynamic ключевое слово - или экземпляр переменной с динамическим, а затем передать его в качестве аргумента конструктора, то AnotherClass(Derived) будет вызван:

BaseClass baseVariable = new Derived(); 
//This will instantiate it using the AnotherClass(Derived) 
AnotherClass anotherVariable = new AnotherClass(baseVariable as dynamic); 

Является ли метод перегрузки рано связан (Оценивается при компиляции время) в C#? Это значение имеет ли какой-либо другой способ или трюк , чтобы определить вызванный в основном вызов другого конструктора классов, чтобы применить вызов конструктора, который принимает в основном аргумент типа основного типа в моем случае без использования dynamic или отражения ?

+0

Вы не создаете 'AnotherClass' в любом месте, поэтому я не вижу, насколько релевант второй фрагмент. –

+0

Обратите внимание, что 'new AnotherClass (base as dynamic)' даже не будет компилироваться, так как 'base' не является допустимым выражением самостоятельно. –

+0

Вопрос обновлен. Я скучаю по чему-то еще? –

ответ

11

Время привязки в C# зависит от того, связано ли привязка dynamic или нет. Как вы видели, если вы используете dynamic, вы получаете разрешение перегрузки во время выполнения; если вы этого не сделаете, вы получите разрешение перегрузки во время компиляции.

Обратите внимание, что даже если разрешение перегрузки связано с динамической типизацией, оно все равно будет использовать информацию, известную во время компиляции, - только выражения, имеющие тип dynamic, используют тип времени выполнения. Пример того, что:

using System; 

class Test 
{ 
    static void Main() 
    { 
     object x = "abc"; 
     dynamic y = 10; 

     Foo(x, y); // Prints Foo(object,int) 
    } 

    static void Foo(object x, int y) 
    { 
     Console.WriteLine("Foo(object,int)"); 
    } 

    static void Foo(string x, int y) 
    { 
     Console.WriteLine("Foo(string,int)"); 
    } 
} 

Если изменить объявленный тип x к dynamic, затем тип исполнения времени будет иметь значение (и он будет печатать Foo(string,int)).

Конечно, это только разрешение перегрузки - наиважнейший является всегда определяется во время выполнения, если вы используете невиртуальный вызов (или вызов не-виртуальный метод, или с помощью base.Foo(...)

+0

«Является ли метод перегрузки ранней привязки (оценен во время выполнения) на C#?» - это была опечатка, я собирался написать о времени компиляции, извинениях. –

+1

@NickL: Это несчастливо :) Отредактировал этот бит из моего ответа. –

+0

Спасибо, сэр. Я считаю своей честью, что вы ответили на вопрос, честно. –

1

. Что касается этого бита:

есть ли другой способ или трюк, чтобы определить в основном производный вызов другого конструктора класса - помимо отражения

?

Единственный способ узнать наиболее производный тип объекта, хранящегося в ссылке, - это опросить его (используя GetType или что-то еще). Поэтому нет, размышления здесь неизбежны.

Если вы уже знаете, что такое самый производный тип, вы можете, конечно, передать его перед тем, как пройти, чтобы соответствующая перегрузка была выбрана во время компиляции. Вы также могли бы использовать var в своем первом фрагменте, чтобы автоматически использовать наиболее производный тип для ссылки.

+0

Благодарим вас за ответ, так как это очень приятное дополнение к ответу Джона Скита. –