странная типизация пространства имен с универсальными классами C # - PullRequest
1 голос
/ 19 октября 2011

У меня есть программа на C # и следующая (полагаю, новичок) проблема:

namespace ObjectReference
{
    public class A<TypeC>
    {
        public B b;

        public void MethodA()
        {
            b = new B(this);
        }
    }
}

и в другом файле в том же проекте:

namespace ObjectReference    
{    
    public class B    
    {   
        public A<TypeC> a;

        public B(A<TypeC> myObjA)    
        {    
            a = myObjA;   
        }
    }    
}

В файле, гдекласс A определен, я получаю эту ошибку в строке "b = new B(this);": "Argument 1: cannot convert from 'ObjectReference.A<TypeC>' to 'ObjectReference.A<ObjectReference.TypeC>'".

Я перепробовал все, не могу решить эту проблему и не понимаю, почему она появляется, всеклассы определены внутри одного и того же пространства имен ObjectReference (то есть классов A, B и TypeC).Это похоже на то, как в классе A он считает тип класса ObjectReference.A<TypeC>, тогда как в классе B он считает тип ObjectReference.A<ObjectReference.TypeC>.

Пожалуйста, сообщите.

Спасибо

Ответы [ 4 ]

2 голосов
/ 19 октября 2011

То, что вы пишете, эквивалентно этому:

public class A<T>
{
    public B b;

    public void MethodA()
    {
        b = new B(this);
    }
}

public class B    
{   
    public A<TypeC> a;

    public B(A<TypeC> myObjA)    
    {    
        a = myObjA;   
    }
} 

Обратите внимание, что я написал класс A как A<T>, а не A<TypeC>. Даже если вы указали правильное имя типа, это допустимый универсальный тип C #, поэтому определение класса A TypeC не совпадает с классом TypeC. Отсюда и сообщение об ошибке, которое вы получаете.

Чтобы сделать эту работу, вам нужно сделать что-то вроде этого:

public class A<T>
{
    public B<T> b;

    public void MethodA()
    {
        b = new B<T>(this);
    }
}

public class B<T> 
{   
    public A<T> a;

    public B(A<T> myObjA)    
    {    
        a = myObjA;   
    }
}    

Тогда вы можете назвать код так:

var a = new A<TypeC>();
a.MethodA();

Надеюсь, это поможет.

1 голос
/ 19 октября 2011

Вы пытаетесь передать обобщенную реализацию A в конструктор B, который принимает неуниверсальное внедрение A. Это, к сожалению, не работает и потребует некоторого переписывания класса B.

Что бы работать, однако, было бы что-то вроде:

namespace ObjectReference
{
    public class B<TypeC>
    {
        public A<TypeC> a;

        public B(A<TypeC> myObjA) 
        {
            a = myObjA;
        }
    }
 }

и затем назовите это как:

b = new B<TypeC>(this);
1 голос
/ 19 октября 2011

Вы пытаетесь указать классу B, чтобы конструктор принимал экземпляр типа A без какой-либо спецификации типа.Вы можете либо обновить класс B, принимая параметр типа, как класс A:

public class B<T>
{
    ...
} 

, либо вы можете сделать конструктор класса b более конкретным, указав для него параметр типа, например:

public B(A<string> myObjA)
{
    a = myObjA;
} 

Для получения дополнительной информации об этом параметре типа, я предлагаю вам посмотреть некоторую информацию о дженериках.Там множество книг и статей!

edit

Я вижу, вы обновили код.Этого все равно будет недостаточно, если TypeC не является реальным типом, который вы нам не дали.Это, однако, было бы очень трудно понять сценарий именования.В основном в классе A вы определяете параметр общего типа, который может быть указан под именем TypeC, а в классе B вы предполагаете, что тип с этим именем существует.Я все еще рекомендую вам почитать дженерики.

0 голосов
/ 19 октября 2011

A<TypeC> - это так называемый открытый универсальный тип, который нельзя передать в качестве аргумента метода.

Чтобы исправить это, необходимо также сделать B универсальным.Использование A<TypeC> в B<TypeC> теперь делает A<TypeC> созданным открытым универсальным типом.Это просто означает, что параметр универсального типа B «выведен» в A<TypeC>.

Возможно, вы захотите взглянуть на страницу MSDN об универсальных классах в C # .

namespace ObjectReference    
{    
    public class B<TypeC>    
    {   
        public A<TypeC> a;

        public B(A<TypeC> myObjA)    
        {    
            a = myObjA;   
        }
    }    
}
...