reflection
, можете начать с этого https://docs.microsoft.com/ru-ru/dotnet/api/system... class Program
{
static void Main(string[] args)
{
const int i1 = 10;
var k1 = i1 + Func(i1);
Console.WriteLine(k1);
var i2 = 10;
var k2 = i2 + Func(i2);
Console.WriteLine(k2);
}
private static int Func(int i)
{
return i * 2;
}
}
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine(10 + Program.Func(10));
int i = 10;
Console.WriteLine(i + Program.Func(i));
}
private static int Func(int i)
{
return i * 2;
}
}
So, как в куче помечено, что класс B унаследован от класса А?
Почему это происходит?
если мы в методе Main напишем B b = new B();, то у нас сначала вызовется статический конструктор в классе B, потом статический конструктор в классе A, потом динамический конструктор в классе A, и динамический конструктор класса В.а над статикой не заморачивайтесь вообще, пока хорошенько не поймете что это такое. это не очень понятно на начальных этапах изучения, и это точно не надо учитывать, пока не дойдете до необходимости создания собственных переопределений статических конструкторов
String
хитрый тип, до недавнего времени его нельзя была задать в роли константы, т.к. он действительно ссылочный тип. Ещё по-умолчанию он интернированный, т.е все одинаковые тексты ссылаются на одним объект. Текст нельзя поменять, можно только создать новый объект с новым текстом.Furthermore, .NET does not guarantee the default implementation of the GetHashCode method, and the value this method returns may differ between .NET implementations, such as different versions of .NET Framework and .NET Core, and platforms, such as 32-bit and 64-bit platforms. For these reasons, do not use the default implementation of this method as a unique object identifier for hashing purposes.
/// <summary>Служит хэш-функцией по умолчанию.</summary>
/// <returns>Хэш-код для текущего объекта.</returns>
[__DynamicallyInvokable]
public virtual int GetHashCode()
{
return RuntimeHelpers.GetHashCode(this);
}
FCIMPL1(INT32, ObjectNative::GetHashCode, Object* obj) {
CONTRACTL
{
THROWS;
DISABLED(GC_NOTRIGGER);
INJECT_FAULT(FCThrow(kOutOfMemoryException););
MODE_COOPERATIVE;
SO_TOLERANT;
}
CONTRACTL_END;
VALIDATEOBJECTREF(obj);
DWORD idx = 0;
if (obj == 0)
return 0;
OBJECTREF objRef(obj);
HELPER_METHOD_FRAME_BEGIN_RET_1(objRef); // Set up a frame
idx = GetHashCodeEx(OBJECTREFToObject(objRef));
HELPER_METHOD_FRAME_END();
return idx;
}
FCIMPLEND
see Knuth Vol 2 p16 (3.2.1.2 Theorem A)