Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 强制转换和As运算符,分别导致强制转换对象和空引用_C#_Unity3d_Casting_Realproxy_As Operator - Fatal编程技术网

C# 强制转换和As运算符,分别导致强制转换对象和空引用

C# 强制转换和As运算符,分别导致强制转换对象和空引用,c#,unity3d,casting,realproxy,as-operator,C#,Unity3d,Casting,Realproxy,As Operator,这个问题几乎纯粹是为了学习。使用的环境是Unity 3D引擎 我一直在使用C#中的RealProxy和MarhalByRefObject类来装饰我的一个类。具体来说,我使用下面的构造函数创建了一个通用代理类。我装饰的类还有一个SerializableAttribute,以及从MarshallByRefObject继承的属性 public DynamicProxy(T decorated) : base(typeof(T)) { } 要获得装饰对象,最简单的代码(无装饰)如下 ClassA t

这个问题几乎纯粹是为了学习。使用的环境是Unity 3D引擎

我一直在使用C#中的RealProxy和MarhalByRefObject类来装饰我的一个类。具体来说,我使用下面的构造函数创建了一个通用代理类。我装饰的类还有一个SerializableAttribute,以及从MarshallByRefObject继承的属性

public DynamicProxy(T decorated) : base(typeof(T))
{
} 
要获得装饰对象,最简单的代码(无装饰)如下

ClassA toDecorate = new ClassA();
DynamicProxy proxy = new DynamicProxy<ClassA>(toDecorate);
Debug.Log(proxy.GetTransparentProxy() as ClassA);
Debug.Log((ClassA)proxy.GetTransparentProxy());    
编辑:经过进一步调查,我注意到as操作员基本上是这样做的

E is T ? (T)(E) : (T)null
现在发生的是is操作符返回false

在这里提供代码以及重现问题所需的所有内容

public class HelloThere: MarshalByRefObject
{
    public void DoStuff()
    {
        //Do some stuff here
        Debug.Log("Doing some stuff");
    }
}
public class Proxy<T> : System.Runtime.Remoting.Proxies.RealProxy
{
    private T _decorated;

    public Proxy(T decorated): base(typeof(T))
    {
        _decorated = decorated;
    }

    public override IMessage Invoke(IMessage msg)
    {
        //Do Stuff Before Function
        //Call Function
        var methodCall = msg as IMethodCallMessage;
        var methodInfo = methodCall.MethodBase as System.Reflection.MethodInfo;
        try
        {
            var result = methodInfo.Invoke(_decorated, methodCall.InArgs);
            return new ReturnMessage(
              result, null, 0, methodCall.LogicalCallContext, methodCall);
            //Do Stuff After function
        }
        catch (Exception e)
        {
            return new ReturnMessage(e, methodCall);
        }
    }
}
公共类hellother:MarshalByRefObject
{
公共空间
{
//在这里做些事情
Log(“做一些事情”);
}
}
公共类代理:System.Runtime.Remoting.Proxy.RealProxy
{
私人T_装修,;
公共代理(T):基础(类型(T))
{
_装饰的=装饰的;
}
公共覆盖IMessage调用(IMessage msg)
{
//先做事再做事
//调用函数
var methodCall=msg作为IMethodCallMessage;
var methodInfo=methodCall.MethodBase作为System.Reflection.methodInfo;
尝试
{
var result=methodInfo.Invoke(_,methodCall.InArgs);
返回新的返回消息(
结果,null,0,methodCall.LogicalCallContext,methodCall);
//在函数之后做一些事情
}
捕获(例外e)
{
返回新的返回消息(e,methodCall);
}
}
}
此外,用于检查每个“铸造”返回内容的代码:

Proxy Proxy=newproxy(newhellother());
Log(proxy.GetTransparentProxy()作为HelloThere);
Log((HelloThere)proxy.GetTransparentProxy());

问题似乎源于Unity 3D引擎本身,特别是它使用的是Mono而不是.NET的变体。产生此错误的版本是Unity v。2019.1.8f1。在Unity 2017.x版本中不存在。正如预期的那样,它在标准.NET开发的应用程序中也不存在。

有点不清楚您在问什么,另一个不起作用的实现在哪里?可能在实际返回的任何类型
GetTransparentProxy
ClassA
之间存在显式转换?@您确实可以说我遗漏了我认为不需要的东西。我已经更新了帖子。如前所述,这更多的是“你以前遇到过这种情况吗”或“你知道这种情况是否会发生”而不是我应该做些什么来解决这个问题。如果你能提供一个解决方案,这样我们就可以对其进行调查,这将非常有帮助。“演员和作为操作员的行为不应该发生变化”——这一假设显然是错误的,因为虽然不能重载
as
运算符,但可以通过显式转换运算符的声明来执行强制转换。我想几乎可以肯定,这就是这里发生的事情。这种重载必须在
ClassA
中定义。
public class HelloThere: MarshalByRefObject
{
    public void DoStuff()
    {
        //Do some stuff here
        Debug.Log("Doing some stuff");
    }
}
public class Proxy<T> : System.Runtime.Remoting.Proxies.RealProxy
{
    private T _decorated;

    public Proxy(T decorated): base(typeof(T))
    {
        _decorated = decorated;
    }

    public override IMessage Invoke(IMessage msg)
    {
        //Do Stuff Before Function
        //Call Function
        var methodCall = msg as IMethodCallMessage;
        var methodInfo = methodCall.MethodBase as System.Reflection.MethodInfo;
        try
        {
            var result = methodInfo.Invoke(_decorated, methodCall.InArgs);
            return new ReturnMessage(
              result, null, 0, methodCall.LogicalCallContext, methodCall);
            //Do Stuff After function
        }
        catch (Exception e)
        {
            return new ReturnMessage(e, methodCall);
        }
    }
}
Proxy<HelloThere> proxy = new Proxy<HelloThere>(new HelloThere());
Debug.Log(proxy.GetTransparentProxy() as HelloThere);
Debug.Log((HelloThere)proxy.GetTransparentProxy());