2014-01-21 4 views
3

Так что я имел этот Singleton кодЭто ошибка? Activator.CreateInstance с конструктором модификатора частного доступа?

public class Foo 
{ 
    private static Foo instance; 
    private Foo() { } 
    public static Foo Instance 
     { 
      get 
      { 
       if (instance == null) instance = Activator.CreateInstance<Foo>(); 
        return instance; 
      } 
     } 
} 

Который не работает, потому что конструктор Foo установлен на частные (бросает исключение, которое не конструктор без параметров для этого класса не найден).

Традиционный new Foo() работает там, хотя (конечно). Я знаю, что Activator не может получить доступ к частному конструктору Foo из-за ограничений доступа, но я думал, что каждый экземпляр объекта был выполнен Activator: так почему Активатор не работает в этом контексте?

Спасибо!

+0

Вероятно, вы имеете в виду другое переопределение [CreateInstance] (http://msdn.microsoft.com/en-us/library/2ca9yys8%28v=vs.110%29.aspx) в вашем «экземпляре было сделано Activator» ? –

+0

Почему? новый Foo() намного короче. – wonko79

+0

@ wonko79 академический вопрос. Кроме того, есть много раз, когда вы вынуждены делать Activator.CreateInstance, и я хотел бы знать. – Gaspa79

ответ

4

Activator ожидается только public строителей. Если вы заинтересованы в чем-то другом, чем public, то вам нужно вызвать его по-разному:

(Foo)Activator.CreateInstance(typeof(Foo), nonPublic:true); 

К сожалению, общая версия на самом деле не дает никаких дополнительных опций ... Что означает, что вы получите некоторые распаковки , Тем не менее, вы также делаете отражение, которое уже медленное ... Поэтому я бы предположил, что это более академично и имеет меньшую производительность.

+0

Ohhh nonPublic: правда, хороший улов. В общей версии этого нет. Благодаря! – Gaspa79

+1

@ Damieh: Хотелось бы, чтобы они ... Это могло бы сэкономить вам какое-то литье ... – Andrew

+0

@ Андрей, это не так, универсальная версия бросается изнутри. –

4

Это не ограничение Activator, но только из CreateInstance метод версия, которую вы выбрали. Измените его до версии CreateInstance(Type type, bool nonPublic) и он будет работать:

if (instance == null) instance = (Foo)Activator.CreateInstance(typeof(Foo), true); 

и замечания от MSDN об этом методе:

Начиная с .NET Framework 2.0 с пакетом обновления 1, этот метод может быть использован для доступа непубличные типы и члены, если вызывающему абоненту предоставлен ReflectionPermission с флагом ReflectionPermissionFlag.RestrictedMemberAccess, и если набор грантов сборки, который содержит непубличные типы и члены, ограничен набором предоставляемых услуг или его подмножеством. (См. Соображения безопасности для отражения.) Чтобы использовать эту функциональность, ваше приложение должно ориентироваться на .NET Framework 3.5 или новее.

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