«Лексическая» область видимости параметров типа в C # - PullRequest
8 голосов
/ 13 мая 2010

У меня есть 2 сценария.

Это не удалось:

class F<X>
{
  public X X { get; set; }
}

ошибка CS0102: тип 'F<X>' уже содержит определение для 'X'

Это работает:

class F<X>
{
  class G
  {
    public X X { get; set; }
  }
}

Единственное логическое объяснение состоит в том, что во втором фрагменте параметр типа X находится вне области видимости, что не соответствует действительности ...

Почему параметр типа должен влиять на мои определения в типе?

ИМО, для согласованности, либо оба должны работать, либо ни один не должен работать.

Есть еще идеи?

PS: я называю это «лексическим», но это, вероятно, не правильный термин.

Обновление:

Согласно ответу Хенка, вот неуниверсальная версия, демонстрирующая то же поведение, но, возможно, ее легче поймать.

Сбой:

class F
{
  class X { }
  public X X { get; set; }
}

Работает:

class X { }
class F
{
  public X X { get; set; }
}

Из того, что я вижу, компилятор C # создает лексическую область видимости на границах определения типа.

Это также означает, что типы и имена членов находятся в одном и том же «местоположении» (или namespace в терминах LISP).

Ответы [ 2 ]

3 голосов
/ 13 мая 2010

Класс G представляет особую область именования. Если вы опустите правила по умолчанию, 2 версии станут:

public F<X>.X F<X>.X { get; set; }    // error
public F<X>.X F<X>.G.X { get; set; }  // OK
2 голосов
/ 13 мая 2010

X определяется как тип в области действия F. Это похоже на это:

class F
{
  public void X();

  public int X(); // Bad, trying to redefine X.

  class G
  {
    public string X(); // OK, different scope
  }
}

F.X не выходит за рамки G, но это не останавливает G от определения нового X.

...