>

반사를 사용하여 클래스의 인스턴스를 만들려고합니다. 그러나 내부적으로 봉인되어 있으며 개인 생성자가 있습니다. 어떻게 시작하고 프레임 워크의 일부로 리플렉션을 사용하여 가져올 수 있습니까?

internal sealed class ABC
{
    private ABC(string password){}
    public static ABC Create(string password){};
}

추가 : System.ServiceModel.Channels.SelfSignedCertificate는 사용하려는 내부 클래스입니다.

  • 답변 # 1

    먼저, 그것이 내부적이라는 사실은 당신이하고 싶은 일을하지 않아야한다는 것을 의미합니다.

    당신이 이루고자하는 다른 길을 진지하게 찾아야합니다.

    불행히도, 당신은 당신이 성취하고 싶은 것을 말하지 않고, 당신이 생각하고 싶은 다음 단계 만 말해 주므로, 내가 당신을 도울 수있는 것입니다.

    이 코드는 작동하며 공개 정적 메소드에 액세스합니다 :

    Type t = typeof(SomeOtherTypeInSameAssembly)
        .Assembly.GetType("ClassLibrary1.ABC");
    MethodInfo method = t.GetMethod("Create",
        BindingFlags.Public | BindingFlags.Static, null,
        new Type[] { typeof(String) },
        new ParameterModifier[0]);
    Object o = method.Invoke(null, new Object[] { "test" });
    
    

    이것은 동일한 어셈블리의 다른 유형, 즉 공용에 액세스 할 수 있어야합니다. 그것을 가지고 있지 않다면, 당신은 타입을 포함하는 Assembly 객체를 잡아야합니다.

  • 답변 # 2

    편집 : 초기화하려는 타입이 .NET 프레임 워크의 일부입니다. 다른 곳에서 참조한 자신의 유형 중 하나라고 생각했습니다.

    이것을 시도하지 말 것을 강력히 권고합니다. Microsoft는 프레임 워크 릴리스간에 내부 클래스를 변경하거나 제거 할 자유가 있습니다. 이와 같은 구현 세부 정보에 의존하면 코드가 엄청나게 부서지기 쉽습니다.

    필요하지 않도록 디자인을 변경하십시오.

    <시간>

    원래 답변 :

    예, 다음과 같이 리플렉션을 사용해야합니다 :

    using System;
    using System.Reflection;
    internal sealed class ABC
    {
        private ABC(string password)
        {
            Console.WriteLine("Constructor called");
        }
    }
    public class Test
    {
        static void Main()
        {
            ConstructorInfo ctor = typeof(ABC).GetConstructors
                (BindingFlags.Instance | BindingFlags.NonPublic)[0];
            ABC abc = (ABC) ctor.Invoke(new object[] { "test" });
        }
    }
    
    

    이런 방식으로 액세스 수정자를 위반하면 ReflectionPermissionFlag.MemberAccess 가 필요합니다.  허가. Create 라는 정적 메소드가 있다는 것을 알고 있다면 , 리플렉션을 통해that을 호출하는 것이 좋습니다 :

    using System;
    using System.Reflection;
    internal sealed class ABC
    {
        private ABC(string password)
        {
            Console.WriteLine("Constructor called");
        }
        public static ABC Create(string password)
        {
            return new ABC(password);
        }
    }
    public class Test
    {
        static void Main()
        {
            MethodInfo method = typeof(ABC).GetMethod("Create",
                BindingFlags.Static | BindingFlags.Public);
            ABC abc = (ABC) method.Invoke(null, new object[]{"test"});
        }
    }
    
    

  • 답변 # 3

    만약 internal  귀하가 아닌 어셈블리에 생성자는 private 로 표시됩니다. 어셈블리 작성자는 객체 생성을 막기 위해 매우 열심히 노력하고 있습니다.

    다음은 사전 공지없이 변경 될 수있는 비공개 클래스 및 방법에 의존하기 때문에 실제로 악의적입니다.

    와이즈 비즈 와이즈 비즈  

    Added: 입니다  사용하려고하는 수업

    이 작업을 수행하지 마십시오. 코드와 모든 노력을 망쳐 놓은 눈이 깜박이면서 프레임 워크가 변경 될 수 있습니다.

    이것은 당신이 할 수 있다고 말했습니다 :

    System.ServiceModel.Channels.SelfSignedCertificate
    
    

    이것은 internal 를 호출합니다  방법 MethodInfo method = Type.GetType(assemblyQualifiedName).GetMethod("Create"); ABC o = (ABC)method.Invoke(null, new[] { "test" }); . 또 다른 옵션은

    static
    
    

    리플렉션을 사용하여 Create 를 허용하는 생성자를로드하는

     매개 변수로 사용하십시오.

    어셈블리 공인 이름을 얻는 쉬운 방법은

    MethodInfo method = Type.GetType(assemblyQualifiedName).GetConstructor(
                            BindingFlags.NonPublic | BindingFlags.Instance,
                            null,
                            new[] { typeof(string) },
                            null
                        );
    ABC o = (ABC)method.Invoke(new[] { "test" });
    
    

    여기서 string   string name = typeof(somePublicType).Assembly.GetType("Namespace.ABC"); 와 공용이고 동일한 어셈블리에있는 유형입니다. .

  • 답변 # 4

    네스트 된 클래스가 아닌 경우 개인 생성자로 클래스를 인스턴스화 할 수 없습니다.

    http://msdn.microsoft.com/en-us/library/kcfb85a6%28VS.71%29.aspx

  • 답변 # 5

    Activator 클래스를 사용하여 인스턴스화

    somePublicType
    
    

    ABC

관련 자료

  • 이전 PHP를 사용하여 Excel XLS를 CSV로 변환하는 방법
  • 다음 symfony - "facebookbundle"symfony2에 대한 구성을로드 할 수있는 확장이 없습니다