Альтернативы вложенным интерфейсам (невозможно в C #) - PullRequest
20 голосов
/ 18 февраля 2010

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

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; }
        .....
    }
    .....
}

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

Ответы [ 5 ]

15 голосов
/ 10 мая 2010

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

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

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 голосов
/ 15 января 2019

Вы можете использовать пространства имен следующим образом:

namespace MyApp
{
    public interface ICountry { }

    namespace Country
    {
        public interface ICountryInfo { }
    }
}

Тогда в MyApp пространстве имен вы можете использовать Country.ICountryInfo, что близко к вашему требованию. Также using alias помогает прояснить код.

2 голосов
/ 06 февраля 2014

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

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;}
}

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

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

Bind<ICountry>().To<Country>();
Bind<ICountryInfo>().To<CountryInfo>().WhenInjectedInto<Country>();
2 голосов
/ 18 февраля 2010

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

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

1 голос
/ 18 февраля 2010

Это будет отлично работать, не нужно вкладывать

public interface ICountry
{
    ICountryInfo Info { get; }
}

public interface ICountryInfo
{
    int Population { get; }
    string Note { get; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...