Что такое эквивалент С# для друга?
Возможный дубликат:
Почему С# не предоставляет ключевое слово друга стиля С++?
Я хотел бы, чтобы частные переменные-члены класса были доступны классу Tester, не подвергая их другим классам.
В С++ я просто объявляю класс Tester своим другом, как это сделать на С#? Может ли кто-нибудь дать мне пример?
Ответы
Ответ 1
Нет прямого эквивалента "friend" - ближайшего доступного (и не очень близко) InternalsVisibleTo. Я использовал этот атрибут только для тестирования - там, где это очень удобно!
Пример: Для размещения в AssemblyInfo.cs
[assembly: InternalsVisibleTo("OtherAssembly")]
Ответ 2
эквивалент шкафа заключается в создании вложенного класса, который сможет получить доступ к закрытым членам внешнего класса. Что-то вроде этого:
class Outer
{
class Inner
{
// This class can access Outer private members
}
}
или если вы хотите поместить класс Inner в другой файл:
Outer.cs
partial class Outer
{
}
Inner.cs
partial class Outer
{
class Inner
{
// This class can access Outer private members
}
}
Ответ 3
Возьмите очень распространенный образец. Класс Factory делает Widgets. Класс Factory должен обманывать внутренности, потому что это Factory. Оба они реализованы в одном файле и по дизайну, желанию и природе тесно связаны классы - на самом деле, Widget на самом деле является только типом вывода из Factory.
В С++ сделайте Factory другом класса Widget.
В С#, что мы можем сделать? Единственное достойное решение, которое пришло мне в голову, - это придумать интерфейс IWidget, который только раскрывает общедоступные методы и имеет интерфейсы IWidget Factory.
Это включает в себя довольно много скуки - снова подвергая все естественные публичные свойства интерфейсу.
Ответ 4
В С# нет ключевого слова 'friend', но один параметр для проверки частных методов - использовать System.Reflection, чтобы получить дескриптор метода. Это позволит вам использовать частные методы.
Учитывая класс с этим определением:
public class Class1
{
private int CallMe()
{
return 1;
}
}
Вы можете вызвать его с помощью этого кода:
Class1 c = new Class1();
Type class1Type = c.GetType();
MethodInfo callMeMethod = class1Type.GetMethod("CallMe", BindingFlags.Instance | BindingFlags.NonPublic);
int result = (int)callMeMethod.Invoke(c, null);
Console.WriteLine(result);
Если вы используете Visual Studio Team System, вы можете заставить VS автоматически генерировать прокси-класс с закрытыми аксессуарами в нем, щелкнув правой кнопкой мыши метод и выбрав "Create Unit Tests..."
Ответ 5
Вы можете имитировать доступ к другу, если класс, которому дано право доступа, находится внутри другого пакета, и если методы, которые вы просматриваете, помечены как внутренние или внутренние, защищены. Вам необходимо изменить сборку, которую вы хотите предоставить, и добавить в AssemblyInfo.cs следующие параметры:
// Expose the internal members to the types in the My.Tester assembly
[assembly: InternalsVisibleTo("My.Tester, PublicKey=" +
"012700000480000094000000060200000024000052534131000400000100010091ab9" +
"ba23e07d4fb7404041ec4d81193cfa9d661e0e24bd2c03182e0e7fc75b265a092a3f8" +
"52c672895e55b95611684ea090e787497b0d11b902b1eccd9bc9ea3c9a56740ecda8e" +
"961c93c3960136eefcdf106955a4eb8fff2a97f66049cd0228854b24709c0c945b499" +
"413d29a2801a39d4c4c30bab653ebc8bf604f5840c88")]
Открытый ключ является необязательным, в зависимости от ваших потребностей.