Набор интересных головоломок по C#
Набор интересных головоломок по C# типа "что выведет этот код, почему и выведет ли вообще что - то". Некоторые простые, некоторые по сложнее. Особенно интересно будет новичкам. В конце поста приведены ответы.
Серия "Что не так с этим кодом":
1.
class One
{
sealed void SealedOnly()
{
// какой - то код
}
virtual void Virt()
{
// какой - то код
}
}
2.
class BaseClass
{
public BaseClass (string Arg0)
{
// какой - то код
}
}
class DerivedClass : BaseClass
{
//еще какой - то код
}
Серия "Что выведет следующий код и почему":
1.
using System;
class Base
{
public virtual void Foo(int x)
{
Console.WriteLine ("Base.Foo(int)");
}
}
class Derived : Base
{
public override void Foo(int x)
{
Console.WriteLine ("Derived.Foo(int)");
}
public void Foo(object o)
{
Console.WriteLine ("Derived.Foo(object)");
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
int i = 10;
d.Foo(i);
}
}
2.
using System;
class Foo
{
static Foo()
{
Console.WriteLine ("Foo");
}
}
class Bar
{
static int i = Init();
static int Init()
{
Console.WriteLine("Bar");
return 0;
}
}
class Test
{
static void Main()
{
Foo f = new Foo();
Bar b = new Bar();
}
}
3.
double d1 = 1.000001;
double d2 = 0.000001;
Console.WriteLine((d1-d2)==1.0);
4.
using System;
class Test
{
static void Main()
{
Foo("Hello");
}
static void Foo(object x)
{
Console.WriteLine("object");
}
static void Foo<T>(params T[] x)
{
Console.WriteLine("params T[]");
}
}
5. Не совсем по теме. Какой модификатор доступа будет у класса А и В:
class A
{
class B
{
}
}
ВНИМАНИЕ, ОТВЕТЫ
Серия "Что не так с этим кодом":
1. Код не скомпилируется, потому что нельзя создать изолированный метод, который не переопределяет базовый метод. Вторая ошибка - нельзя иметь приватный абстрактный или виртуальный методы.
2. Код не скомпилируется, вывалиться ошибка:
class BaseClass
{
public BaseClass (string Arg0)
{
//какой - то код
}
}
class DerivedClass : BaseClass // error CS1501: No overload for method 'BaseClass' takes '0' arguments (DerivedClass must explicitly call BaseClass constructor because there is no parameterless base constructor)
{
//какой - то код
}
Почему? Как Вы знаете, если мы не определили конструктор явно, то компилятор создает за нас конструктор без параметров, конструктор без параметров также генерируется и для производных классов. В примере у нас есть один конструктор, поэтому компилятор не будет генерировать конструктор без параметров для базового класса. Для производного же как раз будет. Проблема заключается в том что, производный класс не может найти конструктор без параметров базового класса, чтобы переопределить его. Для решения этой проблемы, можно добавить конструктор без параметров для базового класса, добавить конструктор с такой же сигнатурой базового класса в производный класс, или добавить конструктор без параметров в производный класс следующим образом:
public DerivedClass(): base("")
{
}
Серия "Что выведет следующий код и почему":
1. Будет напечатано - Derived.Foo(object). Потому что если есть метод подходящий по сигнатуре, то все методы базового класса "отбрасываются" даже если они переопределены в производном классе.
2. На моем компьютере сначала вывелось Bar. а затем Foo. Так происходит, потому что Foo имеет статический конструктор, и он будет вызван только при создании первого экземпляра. Однако, нет гарантий, что слово Bar будет выведено на экран.
3. Ответ "false". Потому что, 1.000001 на самом деле хранится как 1.0000009999999999177333620536956004798412322998046875, и 0.000001 на самом деле хранятся в виде 0.000000999999999999999954748111825886258685613938723690807819366455078125. 0.1 может храниться точно( что тоже может быть не верно).
4. Будет напечатано params T[].
5. Классы "верхнего уровня" по умолчанию являются internal (и могут быть либо internal или public). Вложенный классы по умолчанию являются приватными. Поэтому А - internal, B - private.
3
Подписаться на:
Комментарии к сообщению (Atom)
13 сентября 2010 г. в 01:58 Этот комментарий был удален администратором блога.
13 сентября 2010 г. в 02:59 Этот комментарий был удален автором.
13 сентября 2010 г. в 07:24
2. Нет никаких гарантий что выведется первым - инициализация типов (статические конструкторы/переменные) вызываются при первом обращении к членам класса либо его создании.
З.Ы. у меня выводится Foo, затем Bar
А единственное на что можно полагаться в реальном коде - вот такая ленивая инициализация (и то в .нет4 есть другой инициализатор - Lazy<>):
http://www.yoda.arachsys.com/csharp/singleton.html (пункт 5)