Почему компилятор конфликтует с пространством имен в наследовании - PullRequest
0 голосов
/ 21 мая 2019

В следующем коде

namespace Too
{
    public class Foo
    {

    }
}

namespace Foo
{

    public class Boo : Foo
    {

    }
}

я получаю ошибку 'foo' is a namespace but is used like a type.Ошибка исчезнет, ​​если я полностью укажу имя класса Foo как Too.Foo в наследовании.

Почему компилятор пытается разрешить пространство имен Foo вместо класса в месте, где пространство именне имеет смысла?

Ответы [ 3 ]

4 голосов
/ 21 мая 2019

Компилятору не важно, является ли ваша ссылка классом или пространством имен, когда он впервые разрешает имена.Если имя не полностью определено, оно всегда будет пытаться сначала найти его в локальном пространстве имен, включая само имя пространства имен.Если он не может найти его в локальном пространстве имен, он попытается использовать директивы using.

Причина, по которой он так решается, заключается в том, что вы в конце концов можете создать иерархию пространства имен, и все классы и пространства именразделены ..Таким образом, при разрешении имен компилятор не заботится о типе, а только о пути иерархии.Он будет заботиться о типе, как только найдет совпадение.В этом случае это пространство имен, когда оно ожидает класс и, следовательно, терпит неудачу.

При использовании под-пространств имен и подклассов компилятору будет сложно определить совпадение, если он просто попытается соответствовать одному ион может найти несколько ссылок, если он просто совпадает со случайными пространствами имен в одной сборке.Таким образом, это всегда сначала локальное пространство имен, а затем перемещается вверх по иерархии до других сборок.Если это неясно, поскольку два подпространства имен или классы с одинаковыми именами существуют в разных пространствах имен, на которые ссылаются оба, вы должны быть еще более ясными.

0 голосов
/ 21 мая 2019

Компилятор не может найти class Foo в namespace Foo, где вы пытаетесь наследовать новый класс. Вы должны полностью определить имя, это не то, что вы не можете пропустить или не делать, если:

namespace Foo
{
    using Too;

    public class Boo : Foo // now is ok, compiler will look into `Too` too
    {
    }
}

Без using или полностью определенного компилятора имен даже не заглядывает в namespace Too. Попробуйте использовать любой тип, например List<T> без указания его полностью или без using System.Collections.Generic в методах, та же проблема, вы получите ошибку

Не удалось найти тип или имя пространства имен 'Foo' (отсутствует директива using или ссылка на сборку?)


Что касается ошибки:

CS0118 'Foo' является пространством имен, но используется как тип

Вы получаете это, потому что компилятор находится в области видимости (если я могу так сказать) Foo, который является пространством имен и который вы не должны использовать в качестве базового типа.


@ РенеВогт сформулировал вопрос лучше:

почему компилятор не реализован таким образом, чтобы это могло работать

За ответом мы должны спросить разработчиков. Но в моем понимании это не было бы огромным достижением и стоило бы усилий для достижения этого. Лично я не вижу проблемы с указанием компилятору, где именно искать.

Подумайте об этом случае:

namespace Foo
{
    public class Foo { }
    public class Boo : Foo { }
    public class BooToo : Foo { } // here I want Too.Foo, how?
}

Даже если компилятор изучит namespace Too, у вас все равно будет конфликт.

0 голосов
/ 21 мая 2019

Потому что Foo находится в другом пространстве имен. При наследовании Foo

namespace Foo 
{

    class Boo: Foo {

вы не указываете, на какой Foo вы ссылаетесь. Это Foo пространство имен или Too.Foo

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...