Подтвердить что ты не робот

Альтернативы вложенным интерфейсам (невозможно в С#)

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

public interface ICountry
{
    ICountryInfo Info { get; }

    // Nested interface results in error message:
    // Error    13  'ICountryInfo': interfaces cannot declare types
    public interface ICountryInfo
    {
        int Population { get; }
        string Note { get; }
    }
}


public class Country : ICountry
{
    CountryInfo Info { get; set; }

    public class CountryInfo : ICountry.ICountryInfo
    {
        int Population { get; set; }
        string Note { get; set; }
        .....
    }
    .....
}

Я ищу альтернативу, у кого-нибудь было бы решение?

4b9b3361

Ответ 1

VB.NET позволяет это. Таким образом, вы можете создать сборку VB.NET только с необходимыми определениями интерфейсов:

Public Interface ICountry
  ReadOnly Property Info() As ICountryInfo

  Public Interface ICountryInfo
    ReadOnly Property Population() As Integer
    ReadOnly Property Note() As String
  End Interface
End Interface

Что касается реализации, С# не поддерживает ковариантные типы возврата, поэтому вы должны объявить свой класс следующим образом:

public class Country : ICountry {
  // this property cannot be declared as CountryInfo
  public ICountry.ICountryInfo Info { get; set; }

  public class CountryInfo : ICountry.ICountryInfo {
    public string Note { get; set; }
    public int Population { get; set; }
  }
}

Ответ 2

Это будет работать нормально, нет необходимости в гнезде:

public interface ICountry
{
    ICountryInfo Info { get; }
}

public interface ICountryInfo
{
    int Population { get; }
    string Note { get; }
}

Ответ 3

Если ICountryInfo не имеет оснований для существования вне ICANN, то почему вы не должны просто помещать свойства ICountryInfo в ICANN и отклонять идею вложенных интерфейсов?

Интерфейс, который не имеет смысла без другого интерфейса, не имеет для меня смысла, поскольку интерфейс сам по себе бесполезен, если не реализован классом.

Ответ 4

Если конечная цель заключается в использовании этого с инъекцией зависимости, что неправильно с введением их друг в друга, а не вложением?

public interface ICountry
{
    ICountryInfo Info { get; }
}

public interface ICountryInfo
{
    int Population { get; set; }
    string Note { get; set; }
}

и реализовать как:

public class Country : ICountry
{
    private readonly ICountryInfo _countryInfo;

    public Country(ICountryInfo countryInfo)
    {
        _countryInfo = countryInfo;
    }

    public ICountryInfo Info
    {
        get { return _countryInfo; }
    }
}

public class CountryInfo : ICountryInfo
{
    public int Population { get; set; }
    public string Note { get; set;}
}

Затем, как только вы настроите привязки для ICANN и ICountryInfo, CountryInfo будет вводить в страну всякий раз, когда страна вводится.

Затем вы можете ограничить привязку, если хотите, только ввести CountryInfo в страну и нигде больше. Пример в Ninject:

Bind<ICountry>().To<Country>();
Bind<ICountryInfo>().To<CountryInfo>().WhenInjectedInto<Country>();