using System;
class Base
{
public void DoSomething()
{
Console.WriteLine("Base::DoSomething()");
}
}
class Derived : Base
{
public static void DoSomething()
{
Console.WriteLine("Derived::DoSomething()");
}
}
class Test
{
static void Main()
{
Base a = new Derived();
a.DoSomething();
}
}
На что компилятор выдаёт warning CS0108: The keyword new is required on 'Derived.DoSomething()' because it hides inherited member 'Base.DoSomething()'
Компиляторы С++ такую наглость себе не позволяют, даже несмотря на то, что в отличие от C# — в С++ через экземпляр класса можно вызвать статический метод, а в C# — вызов статических методов через экземпляр класса невозможен.
P.S. Mono 0.3 выдаёт то же предупреждение — видимо, в целях совместимости . Всё это конечно мелочь, но неприятно — ведь компилятору ничего не стоит разобраться, какой-же метод всё-таки вызывается.
using System;
class Base
{
public void DoSomething()
{
Console.WriteLine("Base::DoSomething()");
}
}
class Derived : Base
{
public void Invoke()
{
DoSomething();
}
public static void DoSomething()
{
Console.WriteLine("Derived::DoSomething()");
}
}
А теперь?
new используется для того, чтобы программист мог явно указать свои намерения.
ВВ> class Derived : Base
ВВ> {
ВВ>
ВВ> public void Invoke()
ВВ> {
ВВ> DoSomething();
ВВ> }
ВВ>
ВВ>
Произойдёт абсолютно предсказуемая вещь — будет вызван метод базового класса . Как я уже сказал выше — в C# нельзя вызывать статические методы через this — только через имя класса.
"BiТ" <28769@news.rsdn.ru> wrote in message news:708186@news.rsdn.ru... > Произойдёт абсолютно предсказуемая вещь — будет вызван метод базового класса . Как я уже сказал выше — в C# нельзя вызывать статические методы через this — только через имя класса.
1. Где ты здесь видишь this?
2. Своим ответом ты как раз прекрасно показал, что вышеописанный тобой случай далеко не такой предсказуемый и компилятор поступает более чем правильно
Здравствуйте, Воронков Василий, Вы писали:
ВВ>1. Где ты здесь видишь this? ВВ>2. Своим ответом ты как раз прекрасно показал, что вышеописанный тобой случай далеко не такой предсказуемый и компилятор поступает более чем правильно
"BiТ" <28769@news.rsdn.ru> wrote in message news:708340@news.rsdn.ru... > Здравствуйте, Воронков Василий, Вы писали: > > ВВ>1. Где ты здесь видишь this? > ВВ>2. Своим ответом ты как раз прекрасно показал, что вышеописанный тобой случай далеко не такой предсказуемый и компилятор поступает более чем правильно
А ты покомпилить не пробовал? А то компилятор тоже с тобой не согласен..
Здравствуйте, Воронков Василий, Вы писали:
ВВ>А ты покомпилить не пробовал? А то компилятор тоже с тобой не согласен..
Пробовал. И что же я должен был увидеть необычного ?
Выдаёт известный уже варнинг на 20 строке — и не более...
using System;
class Base
{
public void DoSomething()
{
Console.WriteLine("Base::DoSomething()");
}
}
class Derived : Base
{
public void Invoke()
{
DoSomething();
}
public static void DoSomething()
{
Console.WriteLine("Derived::DoSomething()");
}
}
class Test
{
static void Main()
{
Base a = new Derived();
a.DoSomething();
}
}
BiТ>class Derived : Base
BiТ>{
BiТ> public static void DoSomething()
BiТ> {
BiТ> Console.WriteLine("Derived::DoSomething()");
BiТ> }
BiТ>}
BiТ>
BiТ>ведь компилятору ничего не стоит разобраться, какой-же метод всё-таки вызывается.
Это не особенность компилятора — это особенности реализации рефлекшэна. В качестве примера, объясняющего такое поведение, простенький код:
public class A
{
public string VV()
{
return"A";
}
}
public class B : A
{
public new static string VV()
{
return"B";
}
}
///...bool a = typeof(A).GetMethod("VV").IsStatic; //falsebool b = typeof(B).GetMethod("VV").IsStatic; //true
Это просто некоторые возможности (ИМХО не слишком нужные) принесены в жертву общей красивости реализации.
Я пытался найти формальный ответ, он когда-то проскакивал в старых блогах MS'овцев, но история ссылок не сохранила. Может, кто другой вспомнит. В двух словах, речь там шла о следующем: MSDN дает неправильную информацию на эту тему, в блоге было написано что-то невнятное насчет "внутренних баталий по поводу сокрытия модификаторов, когда ситуация прояснится, MSDN поправят..." Но в MSDN до сих пор так и написано:
Name hiding through inheritance occurs when classes or structs redeclare names that were inherited from base classes. This type of name hiding takes one of the following forms:
...
A method introduced in a class or struct hides all non-method base class members with the same name, and all base class methods with the same signature (method name and parameter count, modifiers, and types).
ВВ>"BiТ" <28769@news.rsdn.ru> wrote in message news:708572@news.rsdn.ru...
ВВ>А что на консоль-то выводится?
Что и ожидалось — Base::DoSomething()
P.S. Речь шля не о том, что я должен был увидеть , а о том — что компилятор и без подсказки способен разрешить имена методов, так как статические методы в C# вызываются сугубо через имя класса( в этом, кстати — компилятор C# отличается от компилятора Mono 0.3 — в последнем статические методы можно вызывать через экземпляр), а метода экземпляра — через имя экземпляра(или в контексте использования внутри метода экземпляра — неявно через this).
Здравствуйте, BiТ, Вы писали:
BiТ>Здравствуйте, Воронков Василий, Вы писали:
BiТ>P.S. Речь шля не о том, что я должен был увидеть , а о том — что компилятор и без подсказки способен разрешить имена методов, так как статические методы в C# вызываются сугубо через имя класса( в этом, кстати — компилятор C# отличается от компилятора Mono 0.3 — в последнем статические методы можно вызывать через экземпляр), а метода экземпляра — через имя экземпляра(или в контексте использования внутри метода экземпляра — неявно через this).
using System;
class Base
{
public void DoSomething()
{
Console.WriteLine("Base::DoSomething()");
}
}
class Derived : Base
{
public void Invoke()
{
DoSomething();
}
public static void DoSomething()
{
Console.WriteLine("Derived::DoSomething()");
}
}
static void Main()
{
new Derived().Invoke();
}
Здравствуйте, BiТ, Вы писали:
BiТ>На что компилятор выдаёт warning CS0108: The keyword new is required on 'Derived.DoSomething()' because it hides inherited member 'Base.DoSomething()' BiТ>Компиляторы С++ такую наглость себе не позволяют, даже несмотря на то, что в отличие от C# — в С++ через экземпляр класса можно вызвать статический метод, а в C# — вызов статических методов через экземпляр класса невозможен.
Компилятор С++ еще очень большое количество наглости себе не позволяпет. Именно по этому писать и отлаживать программы на нем намного сложнее чем на Шарпе.
BiТ> BiТ>P.S. Mono 0.3 выдаёт то же предупреждение — видимо, в целях совместимости . Всё это конечно мелочь, но неприятно — ведь компилятору ничего не стоит разобраться, какой-же метод всё-таки вызывается.
Нда. Ты серьезно считаешь, что всему виной компилятор? Стандарты не пробовал читать? В них как раз все четко изложено.
Шарп по своей спецификации язык претендующий на звание "безопастного". То что ты описал — это средство избавляющее программиста от получения неявного поведения (непредусмотренного программистом). И таких фич в Шарпе много. Например, нельзя объявить во вложеном блоке локальную переменую перекрывающую локальную переменную из внешнего блока.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, BiТ, Вы писали:
ВВ>>1. Где ты здесь видишь this? ВВ>>2. Своим ответом ты как раз прекрасно показал, что вышеописанный тобой случай далеко не такой предсказуемый и компилятор поступает более чем правильно
BiТ>Каждый остался при своём мнении
Ага. Горбатого только...
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.