编辑:This explains everything! – 当您销毁它们时,Unity会在UnityEngine.Objects周围创建托管假包装器.这意味着如果您销毁UEObject,C#包装器仍可能不为空. ==以自定义方式实现,以便在销毁UEObject时检查== null将返回true.这显然不适用于泛型.
这实际上让我疯狂.我有这个方法就在这里:
public static void AssertNotNullAfterAssignment<T>(ref T value, Func<T> get, string msg) where T : class
{
if (value == null)
value = get();
if (value == null)
throw new NullReferenceException(msg);
}
我在一个开头为null的引用上调用它:
AssertNotNullAfterAssignment(ref fovMeshFilter, GetComponent<MeshFilter>, "fovMeshFilter");
什么真的很疯狂,是检查if(value == null)是否返回false!即使值为空!
Here’s a short video我做了这个.
有趣的是,如果我将方法代码复制/粘贴到我在其中使用的方法(在OnEnable中)它可以工作(几乎我在视频中的OnEnable中评论过)
所以…如果它在断言方法之外,它可以工作,但不在内部.我也试过Equals而不是==但是一样.
有人知道发生了什么事吗?
编辑:这是OnEnable,我正在调用断言的方法:
private void OnEnable()
{
//if (fovMeshFilter== null)
// fovMeshFilter= GetComponent<MeshFilter>();
//if (fovMeshFilter== null)
// throw new NullReferenceException("fovMeshFilter");
AssertNotNullAfterAssignment(ref fovMeshFilter, GetComponent<MeshFilter>, "fovMeshFilter");
}
如果我使用未注释的行,它按预期工作,但断言方法不适用于某些只有上帝知道为什么的原因.
编辑1:我们在这里有什么?
EDIT2:
EDIT3:
所以在这个令人敬畏的社区的大力帮助和几个测试后,我来到了解决方案.我本可以发誓这是我尝试过的第一件事!你必须相信我! XD – 只是使用.Equals而不是== – 就像@Edin在他的回答中所示,对一个泛型对象执行==似乎调用System.Object的== – 但是,调用.Equals应该总是解析为正确的等于过载.我不知道为什么会这样,我的意思是,为什么’==’也没有解决正确的过载问题?
解决方法:
您的对象不为null.在调试器中看到null并不意味着它是一个空引用.如果您可以在调试器中展开对象,那么它肯定不是空引用.可能是DebuggerDisplay字符串或ToString()方法在您的情况下返回“null”,但这与null引用不同.
举一个这个类的例子
[DebuggerDisplay("null")]
class A { }
A的实例a
var a = new A();
当您使用鼠标在它上面运行时,它将在调试器中显示为| null.
你的T肯定有这个属性.返回“null”的ToString()重写会在字符串周围添加额外的花括号:a | {null}.
编辑:
看到你的Edit2,让我意识到你的真正问题可能是什么.您的==运算符很可能是重写的,因此在您将类的实例与null进行比较时,它会返回true,尽管实例本身不为null.但是,在通用方法中,不知道您的参数在编译时是什么类型,因此最通用的运算符将应用于您的T参数,即参考比较.这在以下主题中有详细描述:C# generics class operators not working
这可能是OnEnable()中的comparioson工作的原因,而泛型方法中的比较则不然.
然而,这还没有完全证明,因为我看不到你的代码.但你可以验证一下.
以下是运算符与泛型无法正常工作的完整工作示例:
class Person
{
public string Name { get; set; }
public static bool operator ==(Person left, Person right)
{
// we consider Person null when it either has no Name or it is a null reference.
if (object.ReferenceEquals(null, left) || left.Name == null)
return object.ReferenceEquals(null, right);
return left.Equals(right);
}
public static bool operator !=(Person left, Person right) { return !(left == right); }
// Note that == and != operators should ideally be implemented in combination of Equals() override.
// This is only for making an example for this question
}
private static bool IsNull<T>(T val)
{
return val == null;
}
static void Main(string[] args)
{
Person person = new Person();
//this will display: person == null => True
Console.WriteLine("person == null => {0}", person == null);
//this will display: IsNull<Person>(person)=> False
Console.WriteLine("IsNull<Person>(person)=> {0}", IsNull(person));
}
原文地址:https://codeday.me/bug/20190612/1225389.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。