Разница в работе памяти и ссылок в C# и Python?
Разница в работе памяти и ссылок в C# и Python?
Зависит от версии языка, конкретной реализации виртуальной машины и операционной системы. С этого момента вопрос превращается в гадание на кофейной гуще. Формально следует открыть спецификацию языка и убедиться, что детали реализации не задокументированы.

ситуация с ссылочными типами должна быть примерно идентична с Питоном
Да, ситуация очень похожа, и в большинстве случаев так и будет работать. Но как я и предупреждал: "The actual lifetime of a local variable is implementation-dependent."

Но что происходит, когда я так делаю с value типами?
В действительности существует 7 категорий переменных, о которых можно прочитать по ссылке.

Ссылки тут нет (нет же?) и как я понял, то переменная с value типом хранит сам объект, а не ссылку на объект.
Значимые типы могут содержать ссылки, поэтому сборщик мусора молчаливо удалит лишь оболочку и любезно предоставит вам утечку памяти, но это очень редкий случай. В большинстве случаев можно сказать, что значимая переменная хранит значение. Причём не просто хранит, а копирует его при присваивании ("Assignment to a variable of a value type creates a copy of the value being assigned. ").

Получается, my_number просто перезапишет значение с 10 на 20 и все? 
Хороший вопрос, но в нём есть подвох. Выражение int my_number = 10; ничего никуда не записывает, а инициализирует - создаёт привязку переменной my_number к ячейке памяти с числом 10 на этапе компиляции. В итоге ваш пример записывает новое значение в переменную всего один раз и завершается. 

Кроме того, это новое значение вовсе и не значение, а литерал. Встаёт ряд вопросов: "Литералы тоже копируются согласно спецификации, или компилятор умнее?" А если компилятор умный, то почему бы ему не объединить этот код в int my_number = 20; на этапе компиляции? Тут уже не лишним и исходники компилятора + виртуальной машины посмотреть.

Читал про стэк, но ясного понимания пока нет.
Со стеком всё более-менее просто, если не разбираться, какие типы в какой памяти хранятся. Все операции можно разложить в граф, а из графа собрать цепочку простейших операций, которая при обработке LIFO реализует алгоритм. Так вот эта цепочка и называется стеком вызовов. Аналогично существует стек данных.

p.s.
На всякий случай хочу заметить, что в питоне тоже не всё так просто и очевидно. Например:
x = 1; print(id(x))
x = 2; print(id(x))
y = 1; print(id(y))
Локальные переменные хранятся на стекле, и им выделяется конкретное место. В случае 
int my_number = 10;
my_number = 20;
Перезапишется значение на стеке.

Да и нникаких оптимизаций при компиляции в байт код не делается, это делает JIT и то при release сборке. Все ненужные присваивания и неиспользуемые переменные выкидываются.