В .NET существует четкое понятие между ссылочными типами и типами значений.
Тип ссылки - это объект, который размещается в куче (это будет подкласс System.Object). Все, что находится в стеке, это указатель на этот объект. Поэтому вполне допустимо хранить нулевой указатель.
Тип значения - это объект, который размещен в стеке, он будет подклассом System.ValueType. Поскольку тип значения находится в стеке, при передаче его значения функции вы передаете все содержимое объекта.
Типы значений не могут быть нулевыми.
Большинство примитивных типов C # являются типами значений. String - это особый тип примитива, который на самом деле является ссылочным типом.
В .NET 2.0 MS добавила возможность заключать универсальный тип в структуру, чтобы она могла имитировать обнуляемый тип. Что действительно происходит, так это то, что логика внутри структуры Nullable эмулирует для вас нуль.
Они выразили это, используя синтаксическое сокращение, добавив знак вопроса к типу, например:
int? nullableInt = null;
float? nullableFloat = null;
и т.д ...
Если вам не нравится int? синтаксис, вы всегда можете использовать Nullable
public String getBar(Int32 a, String b, Nullable<Int32> c)
В качестве дополнительного примечания я предпочитаю добавлять перегрузку при выполнении того, что вы делаете, просто чтобы сделать синтаксис более приятным.
public String getBar(Int32 a, String b)
{
this.getBar(a,b,null);
}
public String getBar(Int32 a, String b, Nullable<Int32> c)
{
}