Vraag Wanneer is het generieke type opgelost in c #?


Volgens deze antwoord op stackoverloop, het generieke type in C # is opgelost tijdens runtime.

Echter volgens deze antwoord, in C # is het generieke type opgelost tijdens het compileren.

Wat mis ik hier?

Met andere woorden, is het type T opgelost tijdens compile time of run time?

Bijwerken:

Gebaseerd op het antwoord van Oded, in een geval als dit, waarbij het type een gesloten betonsoort is (wat betekent dat het zou worden opgelost tijdens het compileren)

class Program
{
    static void Main()
    {
        var t = new Test<int>();
    }  
}

public class Test<T>
{   
}

zal de MSIL het equivalent hebben van

class Program
{
    static void Main()
    {
        var t = new Test();
    }
}

public class Test<int>
{        
}

13
2017-07-18 21:27


oorsprong


antwoorden:


Het probleem is dat de vraag niet goed gesteld is. Twee mensen beweren tegengestelde dingen: dat typen worden "opgelost" tijdens runtime en dat typen worden "opgelost" tijdens het compileren.

Omdat ze elkaar tegenspreken, moeten ze allebei iets anders betekenen door 'opgelost' te zijn.

Ik weet niet wat het betekent dat een type wordt "opgelost". Ik weet echter wat overbelastingsresolutie is. Wanneer gevraagd om een ​​op te lossen overbelastingsresolutie probleem dat niet gepaard gaat dynamic, de C # -compiler bepaalt welke overbelasting hij moet bellen tijdens het compileren, gebaseerd op de tijd informatie compileren over het generieke type. Dus bijvoorbeeld als u:

static void Main()
{
    var d = new D();
    var p = new P<D>();
    p.N(d);//Displays In class B
}


class B
{
    public void M()// Note, not virtual
    {
        Console.WriteLine("In class B");
    }
} 

class D : B
{
    public new void M()// new, not overload
    {
        Console.WriteLine("In class D");
    }
} 

class P<T> where T : B
{
    public  void N(T t)
    {
        t.M();
    }
}

N belt altijd B.M  zelfs als P<T> wordt geïnstantieerd als P<D>. Waarom? Omdat het probleem van de overbelastingsresolutie bepaalt wat de betekenis is van t.M moet worden opgelost wanneer P<T>.N is gecompileerd, en op dat moment is het beste dat de compiler weet t moet zijn B, dus het kiest B.M.

Als dat niet is wat u bedoelt met "opgelost", verduidelijk dan de vraag.


21
2017-07-18 21:44



Je mist de concepten van open en gesloten generieke types.

In wezen is een gesloten generiek type wanneer u daadwerkelijk bestaande typen op een generieke parameter / s opgeeft (of ze worden afgeleid door de compiler). Bijvoorbeeld:

Nullable<int> nulInt;

Een open generiek type is een type waarbij tijdens runtime een of meer generieke typen moeten worden bepaald (dus, de Nullable<T> klasse is een voorbeeld).


12
2017-07-18 21:30



  1. het eerste antwoord gaat over methodeparameters
  2. en de tweede gaat over generieke typeparameters

dit is wat je mist.

preciezer:  1. C # is standaard statisch getypeerd, dus als u parameters doorgeeft, krijgt u het best passende type en methode. (Zie ook het antwoord over "dynamische" parameters.)  2. Het instellen van een generieke parameter door de syntaxis van C # gaat over statische typen. Het instellen door middel van reflectie gaat over iets anders.

iets anders: "in .NET" heeft elk type een initialisatie fase bij het eerste gebruik tijdens runtime. (zie statische velden en statische constructor)

zo: Alle soorten zijn begonnen tijdens runtime, maar statische typen worden gebruikt (of dynamisch ...) tijdens het compileren moeten ze dat zijn "opgelost".


1
2017-07-18 21:52



Open types (myclass<T>) bestaan ​​geen runtime. Maar ongebonden typen kunnen tijdens runtime bestaan ​​(myclass<>). Om een ​​niet-gebonden type tijdens runtime op te lossen, moet u de operator typeof gebruiken.

Met andere woorden, tenzij het type operator wordt gebruikt, worden generieke typen gesloten tijdens het compileren.


1
2017-08-12 15:47