Альтернативы вложенным интерфейсам (невозможно в С#)
Я использую интерфейсы в этом случае в основном как дескриптор неизменяемого экземпляра объекта. Проблема в том, что вложенные интерфейсы на С# не разрешены. Вот код:
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; }
.....
}
.....
}
Я ищу альтернативу, у кого-нибудь было бы решение?
Ответы
Ответ 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>();