2014-09-29 79 views
2

我在问这是因为我得到一个由WCF运行时生成的对象,并且调用它的GetType()返回一个接口的类型。所以如果你对WCF不熟悉或感兴趣,这是更具体的问题。在什么情况下,GetType()方法将返回接口的类型

这是相关的问题,我问: why an object of WCF service contract interface can be casted to IClientChannel

+1

对此不知情,但这样做可能有帮助吗? http://social.msdn.microsoft.com/Forums/en-US/1e15e6f7-e187-438d-9a75-27e68bc037cf/objgettype-is-returning-an-interface-definition-rather-than-a-class-definition- is-that?forum = netfxbcl – RenniePet 2014-09-29 02:57:26

+0

Thanks @RenniePet,authough我还没有准备好理解那个codeproject文章,它阻止我始终考虑底层模型。 – 2014-09-30 01:51:54

回答

1

我不能编目所有情况可能发生的情况,但这里对这种特殊情况下的一些信息。 CLR有一些工具可以在System.Runtime.Remoting中拦截调用。特别是类RealProxy似乎是特别的。你可以使用它来包装一个对象并拦截对象上方法的调用。这article有很多关于如何使用/实施RealProxy的细节。我发现你可以用它来拦截GetType之类的方法。我怀疑WCF在动态生成的类下也是这样做的。示例使用该文章中的一些示例:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Console.WriteLine(new DynamicProxy(new Calculator(), typeof(ICalculator)).GetTransparentProxy().GetType()); 
    } 
} 

public interface ICalculator 
{ 
    double Add(double x, double y); 
} 

class Calculator : ICalculator 
{ 
    public double Add(double x, double y) 
    { 
     throw new NotImplementedException(); 
    } 
} 

class DynamicProxy : RealProxy 
{ 
    private readonly object _decorated; 
    private readonly Type _reportedType; 
    private static readonly MethodInfo GetTypeMethodInfo = typeof(object).GetMethod("GetType"); 

    public DynamicProxy(object decorated, Type reportedType) 
     : base(reportedType) 
    { 
     _decorated = decorated; 
     _reportedType = reportedType; 
    } 

    private void Log(string msg, object arg = null) 
    { 
     Console.ForegroundColor = ConsoleColor.Red; 
     Console.WriteLine(msg, arg); 
     Console.ResetColor(); 
    } 

    public override IMessage Invoke(IMessage msg) 
    { 
     var methodCall = msg as IMethodCallMessage; 
     var methodInfo = methodCall.MethodBase as MethodInfo; 
     Log("In Dynamic Proxy - Before executing '{0}'", 
      methodCall.MethodName); 
     try 
     { 
      object result; 
      if (GetTypeMethodInfo.Equals(methodInfo)) 
      { 
       result = _reportedType; 
      } 
      else 
      { 
       result = methodInfo.Invoke(_decorated, methodCall.InArgs); 
      } 

      Log("In Dynamic Proxy - After executing '{0}' ", 
       methodCall.MethodName); 
      return new ReturnMessage(result, null, 0, 
       methodCall.LogicalCallContext, methodCall); 
     } 
     catch (Exception e) 
     { 
      Log(string.Format(
       "In Dynamic Proxy- Exception {0} executing '{1}'", e), 
       methodCall.MethodName); 
      return new ReturnMessage(e, methodCall); 
     } 
    } 
}