解决由于编译器生成的副本而导致的歧义?

huangapple go评论73阅读模式
英文:

Solve ambiguity between itself due to compiler generated copies?

问题

General
在使用Unity引擎制作游戏的MOD。

The problem
我尝试使用以下代码附加到activeSceneChanged事件:

SceneManager.activeSceneChanged += OnSceneChanged;

这导致了以下错误:

CS0229 'SceneManager.activeSceneChanged' 和 'SceneManager.activeSceneChanged' 之间的歧义

在检查发生了什么之后,似乎activeSceneChanged成员既是用户生成的,又是[CompilerGenerated]:

解决由于编译器生成的副本而导致的歧义?

What I've tried myself
老实说,我完全不知道如何修复这种问题。我以前从未遇到过这种情况。向我认识的一些其他开发人员提问,但他们也从未见过。使用ILSpy反编译了Unity的DLL文件,只看到编译器生成的代码不在其中(我猜这有道理,因为它是由编译器生成的)。

我真的希望能得到一些关于如何解决这个问题的帮助。

Edit
为了加快进展,这里是mod的Github链接:https://github.com/skarab42/ValheimTwitch

错误出现在Plugin.cs的第93行

英文:

General<br/>
Working on a mod for a game using the Unity Engine.

The problem<br/>
I'm trying to attach to the activeSceneChanged event with this code:

SceneManager.activeSceneChanged += OnSceneChanged;

This results in the error:

> CS0229 Ambiguity between 'SceneManager.activeSceneChanged' and 'SceneManager.activeSceneChanged'

After checking what's going on here, it seems that the activeSceneChanged member is both user generated and [CompilerGenerated]:

解决由于编译器生成的副本而导致的歧义?

What I've tried myself<br/>
I honestly have no idea at all how I'd fix an issue like this. I've never encountered it before. Asked a few other devs I know, but they never seen it either. Decompiled the Unity DLL file with ILSpy, only to see that CompilerGenerated code isn't in there (kind of makes sense since it's generated by the compiler I assume).

I'd really like some help on how to approach this issue and solve it.

Edit<br/>
To help speed things up, here's a Github link to the mod: https://github.com/skarab42/ValheimTwitch

The error pops up at line 93 in Plugin.cs

答案1

得分: 2

通常情况下,当一个类声明一个事件时,C#编译器会生成一个由相同名称的private字段支持的public事件:

[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private static UnityAction&lt;Scene, Scene&gt; activeSceneChanged;

public static event UnityAction&lt;Scene, Scene&gt; activeSceneChanged
{
    add { ... }
    remove { ... }
}

但在这种情况下,似乎Unity的DLL已经被修改,将字段的可访问性从private更改为public。因此,标识符SceneManager.activeSceneChanged现在在事件和字段之间存在歧义。

解决这个问题的理想方法是修复修改Unity DLL的工具。当有相同名称的事件存在时,它不应该更改字段的可访问性。

在此期间,您可以引用未修改的Unity DLL,或者可以使用反射来添加您的事件处理程序:

typeof(SceneManager).GetEvent(&quot;activeSceneChanged&quot;).GetAddMethod()
    .Invoke(null, new object[] { (UnityAction&lt;Scene, Scene&gt;)OnSceneChanged });
英文:

Normally, when a class declares an event, the C# compiler emits a public event that is backed by a private field of the same name:

[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private static UnityAction&lt;Scene, Scene&gt; activeSceneChanged;

public static event UnityAction&lt;Scene, Scene&gt; activeSceneChanged
{
    add { ... }
    remove { ... }
}

But in this case, it seems like the Unity DLL has been modded, with the accessibility of the field changed from private to public. Hence the identifier SceneManager.activeSceneChanged is now ambiguous between the event and the field.

The ideal solution to this problem is to fix the tool that modded the Unity DLL. It shouldn't change the accessibility of a field when there's an event with the same name.

In the meantime, you can reference the unmodded Unity DLL, or you can use Reflection to add your event handler:

typeof(SceneManager).GetEvent(&quot;activeSceneChanged&quot;).GetAddMethod()
    .Invoke(null, new object[] { (UnityAction&lt;Scene, Scene&gt;)OnSceneChanged });

huangapple
  • 本文由 发表于 2023年4月4日 03:27:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75923114.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定