Hello, "igna" > Если интерфейс IDerived унаследован от IBase, то чем class C : IBase, IDerived отличается от class C : IDerived?
От класса не требуется явного указания всех интерфесов которые реализуются интерфейсом IDerived. т.е. для конечного пользователя разницы в том явно было заявлено о реализации IBase или не явно — нет.
Interfaces shall declare that they require the implementation of zero or more other interfaces. If one interface, A, declares that it requires the implementation of another interface, B, then A implicitly declares that it requires the implementation of all interfaces required by B. If a class or value type declares that it implements A, then all concrete instances shall provide implementations of the virtual methods declared in A and all of the interfaces A requires. [Note: The class need not explicitly declare that it implements the interfaces required by A. end note]
Posted via RSDN NNTP Server 2.0
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
TK>Interfaces shall declare that they require the implementation of zero or more other interfaces. If one interface, A, declares that it requires the implementation of another interface, B, then A implicitly declares that it requires the implementation of all interfaces required by B. If a class or value type declares that it implements A, then all concrete instances shall provide implementations of the virtual methods declared in A and all of the interfaces A requires. [Note: The class need not explicitly declare that it implements the interfaces required by A. end note]
Спасибо. Но наверное, если бы в стандарте C# вместо
13.1.4 Implicit reference conversions
The implicit reference conversions are:
...
— From any class-type S to any interface-type T, provided S implements T.
было
13.1.4 Implicit reference conversions
The implicit reference conversions are:
...
— From any class-type S to any interface-type T, provided S (explicit) inherits from T.
, то разницу между class C : IBase, IDerived и class C : IDerived можно было бы заметить. Причем такое поведение не противоречило бы приведенной тобой цитате. Явного указания на то, что обе эти формы объявления/определения класса C эквивалентны, в стандарте C# похоже нет и остается лишь досконально изучить стандарт и убедиться, что противоположного указания тоже нигде нет или поверить гуру на слово
И вот почему вопрос. В документации читаем к примеру:
public abstract class Array : ICloneable, IList, ICollection, IEnumerable
Хотя достаточно было бы:
public abstract class Array : ICloneable, IList
Подумал было, что явное указание ICollection и IEnumerable тут только для документирования, захотел уточнить и спросил здесь
. Результат опроса произвел впечатление. Так, решил я, значит есть все же разница, спросил в форуме, какая? Получит ответ, что нет никакой разницы. Вот те раз, так много заблуждающихся в опросе?
Hello, "igna" > И вот почему вопрос. В документации читаем к примеру: > >
> public abstract class Array : ICloneable, IList, ICollection, IEnumerable
>
> > Хотя достаточно было бы: > >
> public abstract class Array : ICloneable, IList
>
> > Подумал было, что явное указание ICollection и IEnumerable > тут только для документирования.
Именно, что для документирования. Намного удобнее увидеть сразу весь список
интерфейсов чем, вспоминать что там еще может быть в IList. Плюс, при сама
документация может генерироваться автоматически и там уже от утилиты зависит
умеет ли она "сворачивать" список интерфейсов. Скорее всего, этого никто не
делает. Поэтому, и появляются списки из интерфейсов вида ICloneable,
IList, ICollection, IEnumerable но, если взять rotor и посмотреть в файл
array.cs то, можно увидеть что реально указаны только ICloneable,
IList
Posted via RSDN NNTP Server 2.0
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Hello, "igna"
> Спасибо. Но наверное, если бы в стандарте C# вместо >
....
> > , то разницу между class C : IBase, IDerived и class C : > IDerived можно было бы заметить. Причем такое поведение не > противоречило бы приведенной тобой цитате. Явного указания на то, что обе > эти формы объявления/определения класса C эквивалентны, в стандарте C# > похоже нет и остается лишь досконально изучить стандарт и убедиться, что > противоположного указания тоже нигде нет или поверить гуру на слово >
В стандарте есть параграф 20.1.2 Base interfaces
The base interfaces of an interface are the explicit base interfaces and
their base interfaces. In other words, the set of base interfaces is the
complete transitive closure of the explicit base interfaces, their explicit
base interfaces, and so on. An interface inherits all members of its base
interfaces. [Example: In the example
the base interfaces of IComboBox are IControl, ITextBox, and IListBox. In
other words, the IComboBox interface above inherits members SetText and
SetItems as well as Paint. end example]
A class or struct that implements an interface also implicitly implements
all of the interface’s base interfaces.
Кроме того, есть 20.4.4 Interface re-implementation который говорит:
When a class implements an interface, it implicitly also implements all
of that interface’s base interfaces. Likewise, a re-implementation of an
interface is also implicitly a re-implementation of all of the interface’s
base interfaces.
Помоему, стандарт достаточно четко говорит о том, что реализация интерфейса
IDerived означает то, что класс будет реализовывать и IBase также. При этом,
если IBase уже был реализован то, он будет именно реимплементирован (т.е.
будет тоже самое, если указать IBase явно). Исходя из этого, можно получить
то, записи IDerived и IDerived, IBase являются эквивалентными т.к. класс
будет имплементировать (или реимплементировать) IBase в любом случае.
Posted via RSDN NNTP Server 2.0
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, Ocelot, Вы писали:
O>Здравствуйте, igna, Вы писали:
I>>Если интерфейс IDerived унаследован от IBase, то чем class C : IBase, IDerived отличается от class C : IDerived?
O>Ну разница будет хотя бы в случае explicit реализации методов интерфейсов.
Интеллектуальность осуждаемой проблемы поросто поражает. Думаю, следующих спор будет о том где описывать интерфейс до класса, после него, в одтедьном файле или одтельной сборке. Так держать товарищи бойцы!
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, nikov, Вы писали:
N>Здравствуйте, Ocelot, Вы писали:
O>>Здравствуйте, igna, Вы писали:
I>>>Если интерфейс IDerived унаследован от IBase, то чем class C : IBase, IDerived отличается от class C : IDerived?
O>>Ну разница будет хотя бы в случае explicit реализации методов интерфейсов.
N>Приведите пример.
Да пожалуйста.
namespace ConsoleApplication1
{
interface IBase
{
int A();
}
interface IDerived: IBase
{
new int A();
}
class Test: IBase, IDerived
{
int IBase.A()
{
return 1;
}
int IDerived.A()
{
return 2;
}
}
class Test2: IDerived
{
public int A()
{
return 2;
}
}
class Program
{
static void Main(string[] args)
{
IDerived d = new Test();
IBase b = d;
Console.WriteLine(b.A());
Console.WriteLine(d.A());
d = new Test2();
b = d;
Console.WriteLine(b.A());
Console.WriteLine(d.A());
}
}
}
Здравствуйте, Ocelot, Вы писали:
I>>>>Если интерфейс IDerived унаследован от IBase, то чем class C : IBase, IDerived отличается от class C : IDerived?
O>>>Ну разница будет хотя бы в случае explicit реализации методов интерфейсов.
N>>Приведите пример.
O>Да пожалуйста.
O>
O> class Test: IBase, IDerived
O> {
O> int IBase.A()
O> {
O> return 1;
O> }
O> int IDerived.A()
O> {
O> return 2;
O> }
O> }
O> class Test2: IDerived
O> {
O> public int A()
O> {
O> return 2;
O> }
O> }
O>
O>Разница в поведении есть?
Нечестный пример
Попробуйте вот так:
using System;
namespace ConsoleApplication1
{
interface IBase
{
int A();
}
interface IDerived : IBase
{
new int A();
}
class Test : IBase, IDerived
{
int IBase.A()
{
return 1;
}
int IDerived.A()
{
return 2;
}
}
class Test2 : IDerived
{
int IBase.A()
{
return 1;
}
int IDerived.A()
{
return 2;
}
}
class Program
{
static void Main(string[] args)
{
IDerived d = new Test();
IBase b = d;
Console.WriteLine(b.A());
Console.WriteLine(d.A());
d = new Test2();
b = d;
Console.WriteLine(b.A());
Console.WriteLine(d.A());
}
}
}
Теперь классы Test и Test2 действительно отличаются только списком реализуемых интерфейсов. Результат:
Здравствуйте, Ocelot, Вы писали:
O>Мой ответ: нет, явное указание базовых интерфесов может употребляться не только для O>документирования, но и для других целей тоже.
Имелось ввиду в строке указание базовых интерфесов в строке "class C : IBase, IDerived"
Здравствуйте, Ocelot, Вы писали:
O>Мой ответ: нет, явное указание базовых интерфесов может употребляться не только для O>документирования, но и для других целей тоже.
Поменяй тела классов Test и Test2 местами, Test будет вести себя как Test2 в первоначальной версии и наоборот. А от указания или неуказания базового интерфеса ничего не зависит.