2009-11-23 2 views
2

으로 캐스팅 내 응용 프로그램에서 나는 Reflection.PropertyInfo이라는 속성을 '속성'이라고합니다. property.GetValue(myObject,null)을 입력하면 값은 Master.Enterprise입니다. Enterprise는 내 응용 프로그램의 클래스입니다. 따라서 '속성'에는 앱의 클래스에 대한 참조가 포함되어 있습니다.Reflection.PropertyInfo 객체를 해당 유형

런타임에 '속성'을 유형 (Master.Enterprise)으로 캐스팅하여 클래스 유형 인 것처럼 사용할 수 있습니다.

디버거에서 코드를 보면 디버거가 '속성'을 참조하는 유형으로 올바르게 캐스팅하고 디버거에서 Enterprise 클래스의 모든 속성을 볼 수 있기 때문에이 작업을 수행 할 수 있습니다.

어떻게해야합니까?

+2

실제로 디버거 *는 속성 유형에 * 실제 * 캐스트하지 않습니다. 리플렉션을 통해 객체에 대한보고 만합니다. 객체는 * 그것이'Enterprise' 객체라는 것을 압니다. –

+0

"클래스 유형 인 것처럼"작업하고 싶다면 무엇이 될 수 있는지 알아야합니다. 따라서 객체를 캐스팅하거나'is' 연산자를 사용하여 원하는지 확인할 수 있습니다. 그것이 무엇인지 모를 경우, 어쨌든 그것을 할 수는 없습니다. – hangy

+0

교수형에 동의합니다. 귀하의 질문은 명확하지 않습니다. 'property.GetValue'에 의해 리턴 된 오브젝트는 잘 정의 된 런타임 유형을가집니다. '수업 형식처럼 사용하시오.'라는 의미는 무엇입니까? 어떤 종류의 사용을 계획하고 있는지 몇 가지 예를 제시하십시오. –

답변

1

당신은 이런 식으로 뭔가를 할 수 인터페이스를 구현하십시오 : 유형이 현재 AppDomain으로로드되었는지 확인하십시오. 그렇지 않으면 유형을 반영 할 수 없습니다.

Assembly asm = Assembly.GetExecutingAssembly(); 

// The executing assembly can change also; so you can load types from other assemblies 
// use this if the type isn't loaded in this AppDomain yet. 
//Assembly asm = Assembly.LoadFile("path to assembly here", new Evidence()); 

String typeToLoad = "Master.Enterprise"; // this can be from a config or database call 
Type objType = asm.GetType(typeToLoad, true); 

if (!objType.IsPublic) 
return null; 

// make sure the type isn't Abstract 
if (((objType.Attributes & TypeAttributes.Abstract) == TypeAttributes.Abstract)) 
    return null; 

// IEnterprise is the interface that all of the plugin types must implement to be loaded 
Type objInterface = objType.GetInterface("IEnterprise", true); 

if (objInterface == null) 
    return null; 

    var iri = (IEnterprise)Activator.CreateInstance(objType); 
    return iri; 
3
Master.Enterprise enterprise = (Master.Enterprise)property.GetValue(myObject,null); 

또는

Master.Enterprise enterprise = property.GetValue(myObject,null) as Master.Enterprise; 

유형이 호환되지 않는 경우 예외가 발생합니다 첫 번째

. 두 번째는 호환되지 않는 경우 null을 반환합니다.

+0

고맙습니다. 그러나 이것은 효과가 없을 것입니다. 컴파일 타임에 타입을 모른다는 것을 기억하십시오. –

+0

@Randy : 컴파일 타임, 즉 작성중인 코드에서 유형 (또는 적어도 * 가능한 * 유형)을 모르는 경우 어떻게 사용합니까? –

+0

어떤 유형인지 모르는 경우 어떻게 사용하는지 어떻게 알 수 있습니까? – Svish

5

인터페이스 정의가 필요한 것처럼 들리지만, 인터페이스에서 인터페이스를 구현하는 객체를 반환하도록 요구할 수 있습니다. 인터페이스를 구현하는 클래스에 상관없이 해당 인터페이스로 캐스팅 할 수 있습니다.

IEnterprise enterprise = (IEnterprise)property.GetValue(myObject, null); 

리플렉션을 사용하여 반환 된 개체의 메서드와 속성을 호출하는 유일한 방법은 시각적 인 스튜디오 디버거에서 수행하는 것입니다. 객체를 가지고

Assembly execAsm = Assembly.GetExecutingAssembly(); 
object instance = AppDomain.CurrentDomain.CreateInstanceAndUnwrap(execAsm.FullName, "RipperWorkbench.Classes.LoadManager"); // the type name cam come from a variable or someplace else. 

다음 당신은 당신이 다른 방법

Master.Enterprise ent = obj as Master.Enterprise; 
if (obj != null) 
{ 
    ... 
} 

또는 필요로하는 유형으로 캐스트 할 수 있습니다 : 당신은 유형 이름의 문자열이있는 경우

2

컴파일 타임에 형식을 알 수 없으며 해당 형식이 알려진 인터페이스를 구현한다고 가정 할 수없는 경우 C#은 정적 형식의 언어이므로 해당 형식으로 캐스팅 할 수 없습니다.

당신이 베타/그것을 기다릴 사용하려는 경우 당신은 C# 4.0이 작업을 수행 할 수 있습니다, 뭔가 같은 : 내부적으로 얼마나 알아 내기 위해 반사 메소드를 호출합니다 그러나

dynamic obj=property.GetValue(myObject,null); 
obj.CallSomeMethod(); 

주 하기 위해서. 당신은 광대 한 성찰에 의해 오늘 그것을 할 수 있습니다. 반환 된 객체로 구체적으로 수행 할 작업에 대한 자세한 정보를 제공하면보다 자세한 답변을 드릴 수 있습니다.

관련 문제