2011-07-22 20 views
7

Aşağıdaki kod temsilci kovaryans ve Contavariance

namespace ConsoleApplication1 
{ 

public delegate TResult Function<in T, out TResult>(T args); 

class Program 
{ 
     static void Main(string[] args) 
    { 
     Program pg =new Program(); 
     Function<Object, DerivedClass> fn1 = null; 
     Function<String, BaseClass> fn2 = null; 
     fn1 = new Function<object, DerivedClass>(pg.myCheckFuntion) 
     fn2=fn1; 
     fn2("");// calls myCheckFuntion(Object a) 
     pg.myCheckFuntion("Hello"); //calls myCheckFuntion(String a) 
    } 

    public DerivedClass myCheckFuntion(Object a) 
    { 
     return new DerivedClass(); 
    } 
    public DerivedClass myCheckFuntion(String a) 
    { 
     return new DerivedClass(); 
    } 
} 

pasajı düşünün neden temsilci çağrı ve normal metot çağrımı çağrısı farklı yöntemler.

cevap

8

Delege, derleme zamanında myCheckFuntion(Object)'a bağlanır - bir Object kabul eden bir yöntem bulmasını söylüyorsunuz. Bu bağlanma sadece tek bir yöntemdir - gerçek argüman türüne göre yürütme zamanında aşırı yük çözünürlüğü yapmaz.

Eğer "Hello" bir dize ve dize dize dönüştürme aşırı yük çözünürlükte itiraz dizesinden dönüştürme göre tercih edilir, çünkü derleme sırasında myCheckFuntion(String) bağlanacaktır pg.myCheckFuntion("Hello")olduğunu çağırdığınızda.

object text = "Hello"; pg.myCheckFuntion(text); 

sonra olduğunu myCheckFuntion(Object) arayacak: Eğer yazarsanız o

Not.

+0

Eklenecek bir şey yok. +1 –

+0

Jon Skeet'i yenemezsin! – siride

+0

Benim için çok hızlı :( – VMAtm

1

Temsilci nesnesi, yalnızca bir işlev aralığına değil, yalnızca tek bir işleve işaret eder. Co (ntra) varyansı, onu daha geniş bir fonksiyon türünde göstermenizi sağlar. Aynı şekilde, her çeşit değeri object türünde bir değişkene, ancak string türünde bir değişkene daha az atayabilirsiniz. Yine de, bir değişken herhangi bir zamanda sadece bir gerçek tip ve bir gerçek değere sahip olacaktır.

2

fn2 nedeniyle beyan myCheckFuntion(Object a) çağırır: Stringobject daha kısıtlayıcı türü olduğundan

fn1 = new Function<object, DerivedClass>(pg.myCheckFuntion) 
fn2 = fn1; // here you copy the reference 

pg.myCheckFuntion("Hello");myCheckFuntion(Object a) çağırır.

Eğer Object dize dökme eğer:

pg.myCheckFuntion((object)"Hello"); 

diğer yöntem arayacak.