Ограничение типа new()
У меня есть класс Car:
public class Car
{
public int Id { get; set; }
[Range(1, 1000000000, ErrorMessage = "\"{0}\" должна иметь значение между {1} и {2}")]
[Required(ErrorMessage = "\"{0}\" обязательна для заполнения")]
[Display(Name = "Цена")]
public int Price { get; set; }
[Range(1, 1000000000, ErrorMessage = "\"{0}\" должно иметь значение между {1} и {2}")]
[Required(ErrorMessage = "\"{0}\" обязательно для заполнения")]
[Display(Name = "Количество на складе")]
public int Count { get; set; }
public int EquipmentId { get; set; }
public virtual Equipment Equipment { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
И есть интерфейс универсального типа от которого наследуется класс и затем метод этого класса используется в другом классе с бизнес логикой.
Interface:
public interface IModelSort<T> where T : new()
{
IEnumerable<T> GetModelSort<K>(IEnumerable<T> model, Func<T, K> predSort, bool asc);
}
Class:
public IEnumerable<T> GetModelSort<K>(IEnumerable<T> model, Func<T, K> predSort, bool asc)
{
return asc ? model.OrderBy(predSort) : model.OrderByDescending(predSort);
}
Method:
public IEnumerable<T> GetSortedModel<T, K>(IEnumerable<T> model, Func<T, K> predSort, bool asc) where T : new()
{
return new ModelSort<T>().GetModelSort(model, predSort, asc).ToList();
}
Изначально вместо new() было class. Но потом я прочитал про ограничение типа new() и решил попробовать заменить. Но как я думал для этого ограничения у аргумента типа должен быть публичный конструктор без параметров. Но мой класс вообще не имеет конструктора. Почему тогда у меня всё работает с ограничением типа new()? Может если у класса вообще нет конструктора то в нём подразумевается какой то дефолтный которого просто не видно?
Ответы (1 шт):
Если вы сами не указали конструктор, то по умолчанию компилятор сам добавит конструктор без параметров. Если бы у вас вовсе не было конструктора, вы бы не смогли создать экземпляр класса.
Например, определим класс
public class MyClass
{
public int Id {get;set;}
}
И поглядим сгенерированный IL
MyClass.get_Id:
IL_0000: ldarg.0
IL_0001: ldfld UserQuery+MyClass.<Id>k__BackingField
IL_0006: ret
MyClass.set_Id:
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld UserQuery+MyClass.<Id>k__BackingField
IL_0007: ret
MyClass..ctor:
IL_0000: ldarg.0
IL_0001: call System.Object..ctor
IL_0006: ret
MyClass..ctor и есть наш конструктор без параметров.
Мы его можем вызвать вот так
var instance = new MyClass();
