2014-05-20 13 views
10

Questo è per lo più accademico, ma stavo considerando l'implementazione di Equals() per ValueTypes. Il codice sorgente è qui: http://referencesource.microsoft.com/#mscorlib/system/valuetype.cs#38Come posso chiamare FastEqualsCheck()?

Il codice che ha attirato la mia attenzione è stata questa:

// if there are no GC references in this object we can avoid reflection 
    // and do a fast memcmp 
    if (CanCompareBits(this)) 
     return FastEqualsCheck(thisObj, obj); 

FastEqualsCheck() è dichiarato come segue:

[System.Security.SecuritySafeCritical] 
[ResourceExposure(ResourceScope.None)] 
[MethodImplAttribute(MethodImplOptions.InternalCall)] 
private static extern bool FastEqualsCheck(Object a, Object b); 

mia comprensione è che il ' [MethodImplAttribute (MethodImplOptions.InternalCall)] 'indica che questo è implementato nel CLR (fonte non disponibile), ma ho pensato di poterlo chiamare direttamente dal mio codice. Quando provo, ho un SecurityException

ECall methods must be packaged into a system module.

Posso fare queste chiamate me stesso (o sono destinati per il consumo interno)? Se posso chiamarli direttamente, qual è il modo appropriato di farlo?

+0

Correlato: [SecurityException: i metodi ECall devono essere inseriti in un modulo di sistema] (http://stackoverflow.com/questions/11286004/securityexception-ecall-methods-must-be-packaged-into-a-system-module) –

+2

Perché in realtà vuoi chiamarlo? – leppie

+3

@leppie Secondo la domanda, questo è semplicemente accademico, non vi è alcuna applicazione pratica in mente. – Servy

risposta

5

Non è possibile chiamare questi metodi da soli. Sono internal e possono essere richiamati solo con metodi che si trovano nello stesso assembly. Questo è esattamente ciò che ti dice l'eccezione.

Come suggerito nei commenti, è possibile consultare il codice SSCLI per l'implementazione effettiva.

Questo post del blog ti dice esattamente dove trovarlo:

http://blogs.msdn.com/b/xiangfan/archive/2008/09/01/magic-behind-valuetype-equals.aspx

E il link di download per il codice sorgente SSCLI:

http://www.microsoft.com/en-us/download/details.aspx?id=4917

L'implementazione attuale è la seguente:

FCIMPL2(FC_BOOL_RET, ValueTypeHelper::FastEqualsCheck, Object* obj1, 
    Object* obj2) 
{ 
    WRAPPER_CONTRACT; 
    STATIC_CONTRACT_SO_TOLERANT; 

    _ASSERTE(obj1 != NULL); 
    _ASSERTE(obj2 != NULL); 
    _ASSERTE(!obj1->GetMethodTable()->ContainsPointers()); 
    _ASSERTE(obj1->GetSize() == obj2->GetSize()); 

    TypeHandle pTh = obj1->GetTypeHandle(); 

    FC_RETURN_BOOL(memcmp(obj1->GetData(),obj2->GetData(),pTh.GetSize()) == 0); 
} 

Come puoi vedere, eseguono semplicemente un memcmp. Quindi, quello che potresti fare è creare una funzione come questa in una DLL non modificata e chiamarla, che è essenzialmente la stessa.

Problemi correlati