Запретить изменение значения String.Empty

Частично от любопытной точки зрения и отчасти от защиты от потенциальных проблем. Представьте себе, что самое худшее, что может случиться, вызвав следующее (или что-то подобное, но string.Empty является хорошим примером):

typeof(String).GetField("Empty", 
    BindingFlags.Public | 
    BindingFlags.NonPublic | 
    BindingFlags.Static | 
    BindingFlags.GetField
).SetValue(null, "foo" );

Это вызовет проблемы, если там где-то есть код x = myClass.bar ?? string.Empty.

Есть ли способ (похожий на разные домены приложений или аналогичный) для защиты (или обнаружения) кого-то, изменяющего значения, такие как string.Empty или, возможно, SqlDateTime.MinValue (или другие подобные поля только для чтения в .NET)?

Ответ 1

Вы можете определить свои собственные поля const в своей сборке следующим образом:

internal const string Empty = "";

И затем выполните проверку против String.Empty, но это довольно тщетное усилие.

Вам нужно будет выполнять проверку везде, где вы обращаетесь к String.Empty и эффективно ее заменяете (поскольку вы проверили бы в точке сравнения, нет смысла использовать String.Empty поверх вашей версии больше).

Так как он const, значение не может быть изменено, что хорошо, но в то же время, если значение String.Empty когда-либо изменится (как бы маловероятно), вам придется внести изменения к вашему значению, а затем перекомпилируйте все, что ссылается на это поле.

Конечно, вы могли бы сделать свою версию readonly, но тогда вы были бы уязвимы, если бы значение изменилось с помощью отражения, и вы вернетесь туда, где вы начали.

Добавьте к этому факт, что если String.Empty было изменено, пострадали бы не только сравнения с полем, но я бы предположил, что огромное количество методов в BCL просто не будет работать должным образом; глядя через Reflector, казалось бы, он упоминал несколько сотен раз только в mscorlib (.NET 4.0):

references to String.Empty in mscorlib 4.0

Итак, вы можете попробовать и гарантировать, что значение не изменилось, но это просто не практично (это будет вечная игра с кошкой-мышкой), скорее всего, с точки зрения вашего если значение String.Empty было изменено, мир закончится, и программа быстро умрет от ужасной смерти почти сразу после ее изменения.