如何避免 class 和方法的可访问性不一致的编译错误?
How to avoid the compilation error with inconsistent accessibility of class and methods?
我反思了一个 Autodesk 装配并发现了以下内容:
注意PressurePipeNetwork
class是public
,还有一个方法AddLinePipe
也是public
。但是,AddLinePipe
、PressurePartSize
的参数之一是 internal
。
通常我们无法在 .Net 中使用这样的代码进行编译(并且我们会遇到 "Inconsistent Accessibility" 类编译错误)。但不知何故,这个大会逃脱了它。
而且我已经检查过了,程序集中只有一个PressurePartSize
。
当有人说不能完成时,我不太确定。 Autodesk 已经做到了;我得到了组装!
不仅如此,还可以通过某种方式使用 C# 中的库,but with the error message
Autodesk.Civil.DatabaseServices.Styles.PressurePartSize is showing
error that in accessable due to protection level.
怎么做? 我愿意使用任何语言来实现这一点,而不仅仅是C#。或.Net
只是一个建议。可能有两个 PressurePartSize
类:一个 public 一个和一个内部的。图片看不清楚。
像这样:
namespace SampleLib
{
using SampleLib.Internal;
//using SampleLib.Public;
public class PublicClass
{
public unsafe void PublicMethod(InternalClass internalClass) { }
}
}
namespace SampleLib.Internal
{
internal sealed class InternalClass { }
}
namespace SampleLib.Public
{
public sealed class InternalClass { }
}
Error CS0051 Inconsistent accessibility: parameter type 'InternalClass' is less accessible than method 'PublicClass.PublicMethod(InternalClass)'
但是
namespace SampleLib
{
//using SampleLib.Internal;
using SampleLib.Public;
public class PublicClass
{
public unsafe void PublicMethod(InternalClass internalClass) { }
}
}
namespace SampleLib.Internal
{
internal sealed class InternalClass { }
}
namespace SampleLib.Public
{
public sealed class InternalClass { }
}
可以。
更新
只有一个 PressurePartSize,请参阅更新的问题。
一开始他们似乎有 Autodesk.Civil.DatabaseServices.Styles.PressurePartSize
public。然后他们用 public unsafe ObjectId AddLinePipe(LineSegment3d line, PressurePartSize partSize)
创建了一个库并构建了它。然后他们将 Autodesk.Civil.DatabaseServices.Styles.PressurePartSize
更改为 internal,但没有重建调用库。但是 JIT 编译器会在运行时检查可访问性。这就是 exception you mentioned.
的原因
这不能在 C# 中完成。不过,.NET 虚拟机比 C# 更宽松。 许多 特性是 C# 没有公开的。
在 IL 级别,您可以很好地调用 non-public 方法。您还可以使用反射发射使用运行时代码生成来做到这一点。这对于创建快速序列化程序非常有用。
JIT 还可以编译无法验证甚至不正确的 IL。结果未完全定义。
这个程序集是如何创建的?我的第一个想法是这是 IL 链接器工具的结果。 .NET 程序集可以 post-processed 合并或优化它们。这也可能是混淆工具的结果(尤其是无法反编译的方法)。
看起来该工具有一个错误,因为它肯定不是有意创建通常不可调用的 public 方法。
如果您想对此进行试验,您可以将任何程序集反编译为 IL,编辑并编译它。 IL 是 round-trip 我相信的任何东西。
我反思了一个 Autodesk 装配并发现了以下内容:
注意PressurePipeNetwork
class是public
,还有一个方法AddLinePipe
也是public
。但是,AddLinePipe
、PressurePartSize
的参数之一是 internal
。
通常我们无法在 .Net 中使用这样的代码进行编译(并且我们会遇到 "Inconsistent Accessibility" 类编译错误)。但不知何故,这个大会逃脱了它。
而且我已经检查过了,程序集中只有一个PressurePartSize
。
当有人说不能完成时,我不太确定。 Autodesk 已经做到了;我得到了组装!
不仅如此,还可以通过某种方式使用 C# 中的库,but with the error message
Autodesk.Civil.DatabaseServices.Styles.PressurePartSize is showing error that in accessable due to protection level.
怎么做? 我愿意使用任何语言来实现这一点,而不仅仅是C#。或.Net
只是一个建议。可能有两个 PressurePartSize
类:一个 public 一个和一个内部的。图片看不清楚。
像这样:
namespace SampleLib
{
using SampleLib.Internal;
//using SampleLib.Public;
public class PublicClass
{
public unsafe void PublicMethod(InternalClass internalClass) { }
}
}
namespace SampleLib.Internal
{
internal sealed class InternalClass { }
}
namespace SampleLib.Public
{
public sealed class InternalClass { }
}
Error CS0051 Inconsistent accessibility: parameter type 'InternalClass' is less accessible than method 'PublicClass.PublicMethod(InternalClass)'
但是
namespace SampleLib
{
//using SampleLib.Internal;
using SampleLib.Public;
public class PublicClass
{
public unsafe void PublicMethod(InternalClass internalClass) { }
}
}
namespace SampleLib.Internal
{
internal sealed class InternalClass { }
}
namespace SampleLib.Public
{
public sealed class InternalClass { }
}
可以。
更新
只有一个 PressurePartSize,请参阅更新的问题。
一开始他们似乎有 Autodesk.Civil.DatabaseServices.Styles.PressurePartSize
public。然后他们用 public unsafe ObjectId AddLinePipe(LineSegment3d line, PressurePartSize partSize)
创建了一个库并构建了它。然后他们将 Autodesk.Civil.DatabaseServices.Styles.PressurePartSize
更改为 internal,但没有重建调用库。但是 JIT 编译器会在运行时检查可访问性。这就是 exception you mentioned.
这不能在 C# 中完成。不过,.NET 虚拟机比 C# 更宽松。 许多 特性是 C# 没有公开的。
在 IL 级别,您可以很好地调用 non-public 方法。您还可以使用反射发射使用运行时代码生成来做到这一点。这对于创建快速序列化程序非常有用。
JIT 还可以编译无法验证甚至不正确的 IL。结果未完全定义。
这个程序集是如何创建的?我的第一个想法是这是 IL 链接器工具的结果。 .NET 程序集可以 post-processed 合并或优化它们。这也可能是混淆工具的结果(尤其是无法反编译的方法)。
看起来该工具有一个错误,因为它肯定不是有意创建通常不可调用的 public 方法。
如果您想对此进行试验,您可以将任何程序集反编译为 IL,编辑并编译它。 IL 是 round-trip 我相信的任何东西。