2010-08-16 27 views
9

Quali sono le regole relative alla funzione Sovraccarico?C# regole di sovraccarico delle funzioni

ho il seguente codice:

public T genericFunc<T>() where T : Component, new() 
{ 
    T result = new T(); 
    overloadedFunction(result); 
} 

private overloadedFunction (Component c) // catch all function 

private overloadedFunction (DerivedFromComponent dfc) // specific function 

quando chiamo il codice precedente con:

genericFunc<DerivedFromComponent>(); 

mi aspetto che l'overloadedFunction più specifica di essere chiamato, ma la cattura tutte le funzioni si chiama invece , perchè è questo?. Quando si passa attraverso il codice sopra il tipo T è davvero DerivedFromComponent, ho pensato che il CLR ha scelto la migliore corrispondenza possibile in fase di esecuzione!

risposta

14

Il compilatore esegue la risoluzione di sovraccarico entro genericFuncquando il metodo è compilato. A quel punto non sa quale argomento di tipo fornirai, quindi sa solo che può chiamare il primo dei tuoi sovraccarichi.

Il tuo esempio di generics rende la vita più complicata, ma i sovraccarichi sono sempre risolti in fase di compilazione (supponendo che tu non stia usando dynamic).

Un semplice esempio non utilizzano farmaci generici:

void Foo(string text) { } 
void Foo(object o) {} 
... 
object x = "this is a string"; 
Foo(x); 

potrebbe chiamare il secondo overload, perché il tempo di compilazione tipo di x è solo oggetto.

Per ulteriori informazioni, leggere il mio recente article on overloading.

3

Jon Skeet ha ragione riguardo al fatto che la risoluzione del sovraccarico viene determinata al momento della compilazione. Ho pensato di aggiungere un'altra risposta che non era il punto della tua domanda, ma interessante notare comunque.

In C# 4, la parola chiave dinamica può essere utilizzata per rinviare la risoluzione di sovraccarico fino al runtime. Si consideri il seguente frammento di codice che stampa:

Base! 
Derived! 


class Base { 
} 

class Derived : Base { 
} 

void DoSomething(Base x) { 
    Console.WriteLine("Base!"); 
} 

void DoSomething(Derived x) { 
    Console.WriteLine("Derived!"); 
} 

void DoSomething<T>() where T: Base, new() { 
    dynamic x = new T(); 
    DoSomething(x); 
} 

void Main() 
{ 
    DoSomething<Base>(); 
    DoSomething<Derived>(); 
} 
+0

Doh, e nel tempo che mi ha portato a scrivere questo Jon Skeet ha inoltre osservato dinamica. – Josh

+0

Se solo potessi ottenere la gestione di primavera per una nuova copia brillante di VS2010 tutti i miei problemi sarebbero evaporati ... ma purtroppo sono bloccato con .NET 3.5 e VS2008! –

+2

Per essere onesti, non consiglierei di usare il codice sopra per risolvere il problema. Non è un ottimo esempio di un uso giustificato per la risoluzione dinamica. – Josh

Problemi correlati