2008-10-15 2 views
145

Можно создать дубликат:
Why does C# not provide the C++ style ‘friend’ keyword?Что такое эквивалент друга C#?

Я хотел бы частные переменные-члены класса должны быть доступны для класса Tester, не подвергая их к другим классам.

В C++ я просто объявляю класс Tester своим другом, как это сделать на C#? Может ли кто-нибудь дать мне пример?

+2

Вы не должны тестировать частных членов напрямую, как если бы они были доступны как общедоступные. Обычно люди проверяют только среди публичных участников: http://stackoverflow.com/a/5662371/62921 Частные участники будут проверяться косвенно. – ForceMagic 2013-06-21 14:09:19

ответ

213

Нет прямого эквивалента «друга» - ближайшего, доступного (и не очень близко), является InternalsVisibleTo. Я всегда использовал этот атрибут для тестирования - там, где это очень удобно!

Пример: Чтобы быть помещены в AssemblyInfo.cs

[assembly: InternalsVisibleTo("OtherAssembly")] 
+20

+1 для обучения чему-то новому. – Brian 2010-05-11 20:25:46

+7

Интересно отметить, что в VB.NET `Internal` по-прежнему называется` Friend`. – Jeff 2013-10-17 19:55:55

+1

MSDN говорит: «Все непубличные типы в сборке видны другой сборке» Как уродливые! Кто когда-нибудь будет использовать эту ерунду? Я предпочитаю ответ от RobG. – Elmue 2014-01-22 18:52:53

13

Существует не «друг» ключевое слово в C#, но один вариант для тестирования частных методов является использование 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 автоматически генерировать прокси-класса с частными помощниками в нем, щелкнув правой кнопкой мыши метод и выбрав «Создать тесты единиц ...»

35

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

В C++ сделайте Factory другом класса Widget.

В C#, что мы можем сделать? Единственное достойное решение, которое пришло мне в голову, - это придумать интерфейс IWidget, который раскрывает только общедоступные методы и имеет интерфейс Factory IWidget.

Это связано со значительным количеством скуки - снова разоблачить все естественные публичные свойства в интерфейсе.

52

эквивалент шкафа заключается в создании вложенного класса, который будет иметь доступ к частным членам внешнего класса. Что-то вроде этого:

class Outer 
{ 
    class Inner 
    { 
     // This class can access Outer's private members 
    } 
} 

или, если вы предпочитаете ставить внутренний класс в другом файле:

Outer.cs 
partial class Outer 
{ 
} 


Inner.cs 
partial class Outer 
{ 
    class Inner 
    { 
     // This class can access Outer's private members 
    } 
} 
6

Вы можете имитировать доступ друга, если класс, который получает право доступа внутри другого пакет, и если методы, которые вы подвергаете, помечены как внутренние или внутренние. Вы должны изменить сборку, которую хотите поделиться, и добавить в AssemblyInfo следующие настройки.cs:

// Expose the internal members to the types in the My.Tester assembly 
[assembly: InternalsVisibleTo("My.Tester, PublicKey=" + 
"012700000480000094000000060200000024000052534131000400000100010091ab9" + 
"ba23e07d4fb7404041ec4d81193cfa9d661e0e24bd2c03182e0e7fc75b265a092a3f8" + 
"52c672895e55b95611684ea090e787497b0d11b902b1eccd9bc9ea3c9a56740ecda8e" + 
"961c93c3960136eefcdf106955a4eb8fff2a97f66049cd0228854b24709c0c945b499" + 
"413d29a2801a39d4c4c30bab653ebc8bf604f5840c88")] 

Открытый ключ является необязательным, в зависимости от ваших потребностей.

Смежные вопросы