Лучше ли объявлять переменные в интерфейсе или в базовом классе?

#c# #asp.net #blazor

#c# #asp.net #блейзор

Вопрос:

Интерфейсы C#, как я недавно обнаружил, могут объявлять свойства. Предположим , у меня есть несколько занятий Company , Project и User . Для этих классов общими переменными будут Id and Name .

Должен ли я объявить эти переменные в интерфейсе (как показано в блоке кода № 1) или добавить их в базовый класс ( BaseClass ) и наследовать их этим объектам (блок кода № 2)?

Я работаю над приложением Blazor и не понимаю, что из этого является стандартным в C#.

Кодовый блок № 1:

 public interface IBase {  Guid ID { get; }  String Name { get; set; } }  public class Company : IBaseEntity {  public Guid Id { get; set; }  public String Name { get; set; }   public Company()  {  this.Id = Guid.NewGuid();  this.CreatedAt = DateTime.Now;  } }  

Блок кода #2:

 public class BaseClass {  Guid ID { get; }  String Name { get; set; } }  public class Company: BaseClass {  public Company()  {  this.Id = Guid.NewGuid();  this.CreatedAt = DateTime.Now;  } }  

Комментарии:

1. С помощью интерфейса вы вынуждены реализовывать приоры в классе, который реализует интерфейс. Но с базовым классом вы можете переопределить или использовать свойство базового класса. Так что дело не в стандарте, а в требовании

2. Предположим, вам позже тоже понадобится class WorkOrder . У него тоже есть Название? Имя и идентификатор находятся не на одном уровне.

3. Это действительно немного о том, что вы хотите делать с классами. Если я хочу добавить некоторые дополнительные функции, такие как общие методы, которые на самом деле не зависят от реализации, я обычно предпочитаю базовые классы. Если речь идет только о свойствах и методах, которые действительно зависят от дочернего класса, то на самом деле каждый раз потребуется переопределение интерфейсов, которые я предпочитаю. Но обычно в большинстве случаев вы можете добиться того же самого с обоими

Ответ №1:

Я работаю над приложением Blazor и не понимаю, что из этого является стандартным в C#.

Стандарта не существует, потому что базовые классы и интерфейсы имеют разные цели.

Чтобы продемонстрировать:

Я использую что — то вроде вашего IBase для всех классов данных базы данных- мой IDbRecord .

 public interface IDbRecord {  Guid ID { get; }  String Name { get;} }  

и базовый класс:

 public abstract class DbRecordBase : IDbRecord {  public Guid ID { get; set; }  public string Name { get; set; } = string.Empty; }  

Вот некоторые реализации.

 public class Company : IDbRecord {  public Guid ID { get; set; }  public string CompanyName { get; set; } = String.Empty;  public string Name =gt; this.CompanyName; }  public class Car : DbRecordBase, IDbRecord { }  public class Lorry : DbRecordBase, IDbRecord  {  public decimal UnladenWeight { get; set; } = 0m; }  public class Employee : IDbRecord {  public Guid ID { get; set; }  public string FirstName { get; set; } = String.Empty;  public string LastName { get; set; } = string.Empty ;  public string Name =gt; $"{this.FirstName} {this.LastName}"; }  

И то и другое имеет свое применение, но служит разным целям:

Базовые классы предоставляют платформу для шаблонного кода. Car Класс использует шаблон как есть. Lorry добавляет дополнительное свойство. Company и Employee вообще не используйте его.

Интерфейсы предоставляют общий интерфейс, который можно использовать для применения ко всем классам. Я могу использовать следующий метод для всех классов, чтобы извлечь SortedDictionary объект, который я могу использовать для любого выбора Html.

 public SortedDictionarylt;Guid, stringgt; GetLookUpList(Listlt;IDbRecordgt; records)  {  var list = new SortedDictionarylt;Guid, stringgt;();  records.ForEach(record =gt; list.Add(record.ID, record.Name));  return list;  }  

Вы можете ссылаться на все классы через IDbRecord интерфейс, но вы не можете напрямую ссылаться на Lorry класс как на DbRecordBase класс.

Комментарии:

1. В этом есть прекрасный смысл. Однако у меня есть один вопрос. Я не уверен, что это специфично для C#. Но не могли бы вы объяснить, почему Car реализовал IDbRecord , когда DbRecordBase уже реализует его?

2. Я пишу код, который используют другие люди, поэтому мне нравится, чтобы потребитель явно знал, какие интерфейсы реализует каждый класс.

3. Верно. имеет смысл.