Это старый вопрос, но здесь приводится возможное решение, которое не использует интерфейсы.
Вы можете иметь статическую функцию во внутреннем классе, которая устанавливает делегаты во внешнем классе, например:
public class Outer {
private delegate void _operateDlg(Inner inner, bool value);
private static _operateDlg _validate;
static Outer() {
Inner.Init();
}
public void Set(Inner inner, bool value) {
_validate(inner, value);
}
public class Inner {
public bool IsValid {get; private set; }
public static void Init() {
Outer._validate += delegate(Inner i, bool value) {
i.IsValid = value;
};
}
}
}
Вы можете поместить все виды различных делегатов во внешний класс, который вы назначаете с помощью метода Inner.Init (), например, методы, которые возвращают экземпляр класса Inner через закрытый конструктор или методы получения / установки определенного поля. ,
Если вы не против иметь в своем внутреннем классе дополнительную статическую функцию Init (), то это не должно измениться. Но если вы не хотите, чтобы метод Init () был видимым, вы можете использовать рефлексию для его вызова:
using System.Reflection;
public class Outer {
private delegate void _operateDlg(Inner inner, bool value);
private static _operateDlg _validate;
static Outer() {
typeof(Inner).GetMethod("Init",
BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, null);
}
public void Set(Inner inner, bool value) {
_validate(inner, value);
}
public class Inner {
public bool IsValid {get; private set; }
private static void Init() {
Outer._validate = delegate(Inner i, bool value) {
i.IsValid = value;
};
}
}
}
Я знаю, что в любом случае можно использовать Reflection, чтобы обойти ограничения частного доступа, но, на мой взгляд, использовать его только для вызова одного метода Init (), который затем назначает соответствующих делегатов, - намного более чистое и более универсальное решение. Альтернативой может быть вызов рефлексии для каждого отдельного делегата, который вы, возможно, захотите создать, и даже тогда могут быть ограничения (например, невозможность создания делегатов для конструкторов).
Приведенное выше решение не только поддерживает конструкторы обтекания, но и будет использовать Reflection только один раз за время существования программы, поэтому не должно быть заметного снижения производительности, за исключением того факта, что вы используете делегатов для достижения того, что должно были разрешены в качестве прямого доступа в первую очередь. Я не знаю, почему C # не поддерживает это, и я не могу придумать вескую причину, почему это не так.