Ограничение типа 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 шт):

Автор решения: tym32167

Если вы сами не указали конструктор, то по умолчанию компилятор сам добавит конструктор без параметров. Если бы у вас вовсе не было конструктора, вы бы не смогли создать экземпляр класса.

Например, определим класс

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();
→ Ссылка