Кодовые контракты являются относительно новым способом выполнения проверок ввода и вывода функций. Там, где они отличаются от стандартной проверки типа Assert
, выполняется то, что сгенерированный IL, который проверяет ввод, проверяет его непосредственно перед вызываемой функцией и код, который проверяет вывод, после того, как ваша функция действительно вышла.
Почему это полезно?
Ну, это мешает вам изменять переменные после того, как вы думаете, что ваша функция может вернуться, тем самым потенциально представляя ошибки.
Вот пример.
public void doSomething(SomeObject foo)
{
Contract.Requires<ArgumentNullException>(foo != null);
}
Теперь в кодовых контрактах требуется, чтобы перед этой проверкой не было кода. В сгенерированном ИЛ значение foo
проверяется PRIOR на вызов. Это надежный способ гарантировать, что ваш вход будет таким, как ожидалось.
Другой - это Contract.Ensures
. Это в основном похоже на Requires
, но работает с вашим возвращаемым значением.
public int doSomethingElse()
{
Contract.Ensures(Contract.Result<int>() != 0);
int ret = 1;
return ret;
}
Это было бы особенно полезно, если бы у вас было несколько путей выхода из вашей функции ...
public int someBadFunction()
{
Contract.Ensures(Contract.Result<int>() != 0);
if(....)
{
if(....) return 2;
if(....) return 8;
}
return 3;
}
В C# 5 и ранее, чтобы дать автоматическим реализованным свойствам значение по умолчанию, необходимо сделать это в конструкторе.
способность иметь автоматические инициализаторы свойства включена начиная с C# 6.0. Синтаксис:
public int X { get; set; } = x; // C# 6 or higher
DefaultValueAttribute ТОЛЬКО работают в по сравнению с разработчиком. Это не инициализирует свойство к тому значению.
Видят , атрибут DefaultValue не работает с моим Автоматическим Свойством
Лично, я не вижу точку создания его свойство вообще, если Вы не собираетесь делать что-нибудь вообще вне автосвойства. Просто оставьте его как поле. Преимущество инкапсуляции для них, объект является просто отвлекающими маневрами, потому что нет ничего позади них для инкапсуляции. Если когда-нибудь необходимо изменять конкретную реализацию, Вы все еще свободны осуществить рефакторинг их как свойства, не повреждая зависимого кода.
Хм..., возможно, это будет подчиненным вопросом самим по себе позже
При встраивании начального значения для переменной, это будет сделано неявно в конструкторе так или иначе.
я утверждал бы, что этот синтаксис был лучшей практикой в C# до 5:
class Person
{
public Person()
{
//do anything before variable assignment
//assign initial values
Name = "Default Name";
//do anything after variable assignment
}
public string Name { get; set; }
}
, Поскольку это дает Вам, четкий контроль стоимостей заказов присвоен.
С C#6 существует новый путь:
public string Name { get; set; } = "Default Name"
Иногда я использую это, если я не хочу, чтобы он был на самом деле установлен и сохранен в моем дб:
class Person
{
private string _name;
public string Name
{
get
{
return string.IsNullOrEmpty(_name) ? "Default Name" : _name;
}
set { _name = value; }
}
}
, Очевидно, если это не строка тогда, я мог бы сделать объект nullable (дважды?, интервал?) и проверка, если это является пустым, возвратите значение по умолчанию или возвратите значение, на которое это установлено.
Тогда я могу сделать регистрацию моего репозитория, чтобы видеть, является ли это мое значение по умолчанию, и не сохраняются или делают закулисную регистрацию для наблюдения истинного состояния отступающего значения, перед сохранением.
Hope, которая помогает!
Вы попытались использовать DefaultValueAttribute или ShouldSerialize и методы Сброса в сочетании с конструктором? Я чувствую, что один из этих двух методов необходим при создании класса, который мог бы обнаружиться на поверхности разработчика или в сетке свойства.
В C# 6 и выше Вас может просто использовать синтаксис:
public object Foo { get; set; } = bar;
Примечание, что для имения readonly
свойство просто опускают набор, как так:
public object Foo { get; } = bar;
можно также присвоиться readonly
автосвойства от конструктора.
До этого я ответил как ниже.
я постарался бы не добавлять значение по умолчанию к конструктору; оставьте это для динамических присвоений и постарайтесь не иметь две точки, в которых переменная присвоена (т.е. значение по умолчанию типа и в конструкторе). Обычно я просто записал бы нормальное свойство в таких случаях.
Еще одна опция состоит в том, чтобы сделать, какой ASP.NET делает и определяет значения по умолчанию через атрибут:
http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx
небольшой полный пример:
using System.ComponentModel;
private bool bShowGroup ;
[Description("Show the group table"), Category("Sea"),DefaultValue(true)]
public bool ShowGroup
{
get { return bShowGroup; }
set { bShowGroup = value; }
}