목표는 my 메서드를 호출 한 형식을 기반으로 일반 인스턴스를 만드는 것입니다.StackFrame에서 Type T 가져 오기
제네릭에서 호출 할 때 StackFrame은 닫힌 정의 형식 인수 대신 열린 정의 형식 매개 변수 만 포함하는 것으로 나타납니다. StackFrame에서 형식 인수를 얻으려면 어떻게해야합니까? this question와 유사합니다. Log.Debug가 닫힌 메소드에서 호출되기 때문에 내 상황이 다르다고 생각하고 싶습니다.
StackFrame이 올바른 방법이 아닌 경우 IoC 이외의 제안이 있습니까? 이 코드는 Unity 컨테이너에 대한 참조를 사용할 수없는 경우를 채우기위한 것입니다.
using System;
using System.Reflection;
namespace ReflectionTest
{
public class Logger
{
private readonly string loggerName;
protected Logger(string loggerName) { this.loggerName = loggerName; }
public void Debug(string message) { Console.WriteLine(string.Format("{0} - {1}", loggerName, message)); }
}
public class Logger<T> : Logger
{
public Logger() : base(typeof(T).FullName) { }
}
public static class Log
{
public static void Debug(string message)
{
// Determine the calling function, and create a Logger<T> for it.
System.Diagnostics.StackFrame frame = new System.Diagnostics.StackFrame(1);
MethodBase method = frame.GetMethod();
/// When method is from a generic class,
/// the method.ReflectedType definintion is open: Type.ContainsGenericParameters is true
/// How do I get the generic parameters of method.ReflectedType so
/// Activator.CreateInstance() will not throw?
Type logType = typeof(Logger<>);
Type constructed = logType.MakeGenericType(new Type[] { method.ReflectedType });
Logger logger = (Logger)Activator.CreateInstance(constructed);
logger.Debug(message);
}
}
public class MyBase<T>
{
public void Run()
{
Log.Debug("Run Generic"); // throws on Activator.CreateInstance()
}
}
class Program
{
static void Works()
{
Log.Debug("Run NonGeneric"); // works
}
static void DoesNotWork()
{
MyBase<int> b = new MyBase<int>();
b.Run();
}
static void Main(string[] args)
{
Works();
DoesNotWork();
}
}
}
사실 System.Diagnostics에는 * Process 클래스처럼 유용합니다. Process.Start). 그래서 네임 스페이스는 신뢰할 수없는 것을 전달하지 않습니다. 스택 프레임을 신뢰할 수 없도록 만드는 인라인과 같은 것에 대해 알아야합니다. –
위대한 설명. StackFrame을 사용하는 나의 방법뿐만 아니라 "누가 당신을 호출했는지"라는 전체 개념이 .NET에서의 잘못된 사고라고 생각됩니다. – ErnieL
C# vNext에서 우리는이 상황에서 유용 할 수있는'CallerFilePath','CallerLineNumber','CallerMemberName' 매개 변수 속성을 얻을 것으로 예상합니다. –