我问这个是因为我得到了一个由WCF运行时生成的对象,并且在其上调用GetType()会返回一个接口类型。因此,如果您对WCF不熟悉或不感兴趣,这是更具体的问题。
这是我问的相关问题: why an object of WCF service contract interface can be casted to IClientChannel
答案 0 :(得分: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);
}
}
}