Considerate i seguenti metodi in C#:Perché il metodo GetHashCode() è compilato in modo diverso per DateTime rispetto ad altre strutture?
public static int HashCodeFunction(Decimal value)
{
return value.GetHashCode();
}
public static int HashCodeFunction(Int64 value)
{
return value.GetHashCode();
}
public static int HashCodeFunction(DateTime value)
{
return value.GetHashCode();
}
Guardiamo le istruzioni generate dal compilatore:
Per il metodo Decimal
:
ldarga.s Parameter:System.Decimal value
call Method:System.Decimal.GetHashCode()
ret
Per il metodo Int64
:
ldarga.s Parameter:System.Int64 value
call Method:System.Int64.GetHashCode()
ret
Per il metodo DateTime
:
ldarga.s Parameter:System.DateTime value
constrained Type:System.DateTime
callvirt Method:System.Object.GetHashCode()
ret
Perché il metodo DateTime.GetHashCode()
essere trattata come una chiamata virtuale di Object.GetHashCode()
, considerando che c'è un GetHashCode()
metodo ignorato per il DateTime
struct?
Inoltre, posso creare un metodo che chiama direttamente il metodo System.DateTime.GetHashCode()
senza la chiamata virtuale utilizzando il seguente codice:
DynamicMethod myDynamicMethod = new DynamicMethod("myHashCodeMethod", typeof(int), new[] { typeof(DateTime) });
ILGenerator gen = myDynamicMethod.GetILGenerator();
LocalBuilder local = gen.DeclareLocal(typeof(DateTime));
gen.Emit(OpCodes.Ldarga_S, local);
gen.Emit(OpCodes.Call, typeof(DateTime).GetMethod("GetHashCode"));
gen.Emit(OpCodes.Ret);
quindi creare un delegato per testarlo:
Func<DateTime, int> myNewHashCodeFunction = (Func<DateTime,int>)myDynamicMethod.CreateDelegate(typeof(Func<DateTime, int>));
DateTime dt = DateTime.Now;
int myHashCode = myNewHashCodeFunction(dt);
int theirHashCode = dt.GetHashCode();
// These values are the same.
Solo curioso perché il metodo è implementato in questo modo per impostazione predefinita per Int64
e Decimal
, ma non DateTime
.
affermazioni straordinarie richiedono prove straordinarie, non vedo alcuna. –