TestProperty
에 귀하의 속성은 컴파일되지 않습니다
그래서 당신이해야 할 모든이 같은 뭔가 재산의 설정 기능을 변경하는 것입니다 대리자는 특성 인수로 허용되지 않기 때문입니다. 허용되는 유형에 대한 자세한 내용은 this answer from Eric Lippert을 참조하십시오.
리플렉션을 사용하여 해결 방법에 대해 : System.Type
및 string
이 유효한 속성 인수 유형이므로 메서드를 소유 한 형식과 특성에서 메서드 이름을 확실히 지정할 수 있습니다. 다음과 같은 내용이 있습니다.
[AnnotatedProperty(typeof(Test), "TestEvaluator")]
public string TestProperty { get; set; }
그러나 속성을 설정하면 위임자와 아무 관계가 없습니다. 속성은 리플렉션을 사용하여 런타임 중에 (특히 MemberInfo.GetCustomAttributes(...)
을 사용하여) 읽을 수 있고 속성 값을 기반으로 모든 작업을 수행하고 분석 할 수있는 메타 데이터입니다. 이 모든 작업은 수동으로 수행해야합니다. 안타깝게도 .NET Framework는 멤버에 적용된 특성을 기반으로 일부 작업을 자동으로 수행하는 기능을 제공하지 않습니다. 이렇게하면 부동산 변경 통지가 훨씬 쉬워집니다.
따라서 속성을 수동으로 처리해야합니다. 즉, get
및 set
접근자를 구현하고 속성이 해당 속성에 적용되는지 여부를 확인하고 실행해야하는 대리자를 결정한 다음 리플렉션을 사용하여 실행합니다. 물론, setter에서 메소드에 대한 호출을 대신 추가하기 때문에 이치에 맞지 않습니다.
TL; DR :
가능한 해결 방법 : 당신은 PostSharp 봐, .NET에서 aspect 지향 프로그래밍을 지원하는 라이브러리가 있어야합니다. 컴파일 후 보일러 플레이트 코드를 메소드 나 다른 멤버에 주입하는 데 사용할 수 있습니다. MSIL 코드를 분석하고 소위 "aspect"(실제로는 여러분의 것과 같은 속성)를 검색하여이를 수행합니다. 발견되면 속성에 지정된대로 MSIL을 수정합니다. PostSharp 기본 속성/애스펙트에서 속성을 추출한 다음 적절한 메소드를 대체해야합니다.귀하의 경우에는 LocationInterceptionAspect
에서 파생 된 후 OnSetValue(...)
메서드를 재정의해야합니다. 이 방법에서는 위의 속성 인수를 사용하여 대리인을 결정한 다음 리플렉션을 사용하여이를 호출합니다. "Intercepting Properties and Fields" in the PostSharp documentation이 방법에 대해 아주 잘 설명합니다.
난 당신이 같은 끝낼 것이라고 생각 : 나는 오류의 대부분을 생략
public class Test
{
public static void TestMethod(string someMessage)
{
MessageBox.Show(someMessage);
}
[ExecuteDelegateOnPropertySetAspect(typeof(Test), "TestMethod", new object[] { "Hello world!" })]
public string TestProperty { get; set; }
}
참고 :
public class ExecuteDelegateOnPropertySetAspect : LocationInterceptionAspect
{
public ExecuteDelegateOnPropertySetAspect(Type methodOwner, string methodName, object[] arguments)
{
this.MethodOwner = methodOwner;
this.MethodName = methodName;
this.Arguments = arguments;
}
public Type MethodOwner { get; set; }
public string MethodName { get; set; }
public object[] Arguments { get; set; }
public override void OnSetValue(LocationInterceptionArgs args)
{
// get method with the specified name from the specified owner type
MethodInfo method = this.MethodOwner.GetMethod(this.MethodName);
// method must be static, otherwise we would need an instance to call it
if (method != null && method.IsStatic)
{
if (method.GetParameters().Length == this.Arguments.Length)
{
// call the method with the given arguments
method.Invoke(null, this.Arguments);
}
}
// execute the original setter code
args.ProceedSetValue();
}
}
그리고 코드에서이 부분을 당신의 재산에 적용 할
그것을 간단하고 짧게 유지하기위한 널 검사.
러빙 http://www.postsharp.net/ – user1514042