#c# #generics #namespaces
#c# #универсальные классы #пространства имен
Вопрос:
У меня есть программа на 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>
.
Пожалуйста, посоветуйте.
Спасибо
Комментарии:
1. Все ли в одной сборке?
2. Покажите объявление
TypeC
. У вас есть какие-либо инструкции в ваших файлах?using
Похоже, есть два определенияTypeC
.
Ответ №1:
То, что вы пишете, эквивалентно этому:
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();
Я надеюсь, что это поможет.
Ответ №2:
Вы пытаетесь указать классу B иметь конструктор, принимающий экземпляр типа A без какой-либо спецификации типа. Вы можете либо обновить класс B, приняв параметр типа, как и класс A:
public class B<T>
{
...
}
или вы можете сделать конструктор класса b более конкретным, указав для него параметр типа, например:
public B(A<string> myObjA)
{
a = myObjA;
}
Для получения дополнительной информации об этом параметре типа я предлагаю вам посмотреть некоторую информацию об универсальных классах. Существует множество книг и статей!
Редактировать
Я вижу, вы обновили код. Этого все равно будет недостаточно, если TypeC не является фактическим типом, который вы нам не указали. Однако это было бы очень сложным для понимания сценарием именования. По сути, в классе A вы определяете параметр универсального типа, который может быть указан под именем TypeC, а в классе B вы предполагаете, что тип с таким именем существует. Я все же рекомендую вам немного почитать о дженериках.
Комментарии:
1. Вот TypeC, определенный, как я уже сказал, в том же проекте, в том же пространстве имен, в другом файле: namespace ObjectReference { public class TypeC { public string stringC; public TypeC() { stringC = «stringC»; } } } Поэтому я указываю параметр type в конструкторе в classB. Фрагмент, который я привел здесь, является упрощенной версией моего фактического кода, но это проблема, с которой мне нужно справиться. Я буду подробно читать о дженериках, однако я надеялся, что у кого-то есть идея о том, как это решить. Спасибо
2. @laail: Пожалуйста, добавьте эту информацию в свой вопрос и правильно отформатируйте ее.
Ответ №3:
Вы пытаетесь передать универсальную реализацию 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);
Ответ №4:
A<TypeC>
это так называемый открытый универсальный тип, который вы не можете передать в качестве аргумента метода.
Чтобы исправить это, вам также нужно сделать B
generic. Использование 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;
}
}
}