标签: access-modifiers

通过针对具有公共成员的修改后的程序集进行编译来访问私有成员的反射的替代方法

概括

我寻找一种通过反射访问私人成员的替代方法,似乎我找到了一个。
剩下的问题是:

  1. 无论环境如何,它总是有效吗?
  2. 有什么理由不使用它?

寻找替代方案的原因

使用反射或一些稍微简化它的反射工具是以编程工作和计算资源方面的开销为代价的。特别是如果您需要使用私有类型的实例,它会变得非常麻烦。
此外,您还失去了IDE 的代码完成和其他功能的优势。即使是简单的拼写错误也可能导致错误,因为您使用字符串进行反射。

替代方法

获取原始程序集并将私有/非公共成员更改为公共成员(通过 IL 编辑器、反编译器或 Cecil)。
将这个修改后的程序集添加到您的引用中,然后您就可以轻松开发,因为编译器认为您可以访问它们(对于这个版本,您可以访问它们)。
然而,如果您针对原始程序集使用已编译的程序集,则这只适用于类型,因为如果您访问其他私有成员,则会在运行时遇到访问冲突异常。
除非您启用“允许不安全代码”,否则它似乎不再关心访问修饰符。
我没有找到有关此功能的任何信息(?),但此选项和代码中相关的不安全关键字通常主要用于指针。

对我来说它有效,但我不知道这种行为在其他情况下(例如不同的操作系统和 CLR 版本)是否一致。
另外,如果还有其他原因不使用此技术。

大会宣传员

我编写了一个工具来创建程序集的副本,其中所有成员都是公共的(类型、方法、字段、属性的 getter 和 setter)。

https://github.com/CabbageCrow/AssemblyPublicizer

它使用起来很简单,在 Windows 上您甚至可以将程序集拖放到 exe 上。

潜在的工作流程

  1. 公开原始程序集(使用工具)
  2. 使用公开的程序集作为参考
  3. 开发时无需任何思考即可访问私人成员,并对此感到高兴
  4. 启用“允许不安全代码”进行编译
    请参阅https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/unsafe-compiler-option
  5. 将您自己的程序集与原始未修改的程序集一起使用,它仍然可以神奇地访问私有成员。

c# reflection unsafe private access-modifiers

6
推荐指数
0
解决办法
401
查看次数

Java 定义显式的 package-private 修饰符

显然,Java 有一个访问级别包私有,这是通过不添加任何显式修饰符来实现的。

但是有没有办法显式添加这个修饰符呢?当我们只想使用包中的成员时,我们需要省略访问级别,这有点令人困惑。

如果没有办法,为什么包私有决定作为默认级别?

例如,如果默认级别是公共的,那么我们会更有意识地定义相关的访问级别。

这与为什么使用它的问题不重复,因为我知道为什么,我只是不知道为什么它是隐式定义的并且不能显式定义。

编辑

您可以使用 Lombok 的@PackagePrivate显式定义它

用于指示带注释的实体具有包私有访问级别的明确意图。目前由 FieldDefaults 和 Value 使用,以避免将字段设为公共、受保护或私有字段之一。

@PackagePrivate String thanksLombok;
Run Code Online (Sandbox Code Playgroud)

java access-modifiers access-levels

6
推荐指数
1
解决办法
3401
查看次数

使用私有/受保护常量测试类

在测试类方法时,有时我需要将返回值与某个类中定义的某个常量进行比较。

class FooBar
{
    const RANDOM = 18;
}
....
// Somewhere in test...
$this->assertEquals(FooBar::RANDOM, $mock->doSomething());
Run Code Online (Sandbox Code Playgroud)

现在,从 PHP 7.1 开始,可以使用可见性修饰符定义类常量,这可以更改为:

private const RANDOM = 18;
Run Code Online (Sandbox Code Playgroud)

然而,这会阻止测试工作,因为现在我们正在尝试访问私有常量。

所以现在我们有两个选择:

  1. 将常量声明为公共常量。
  2. 在测试中使用反射。这意味着测试变成:

$this->assertEquals( (new ReflectionClass(FooBar::class))->getConstant('RANDOM'), $mock->doSomething() );

第一种方法感觉非常错误,因为我们只是为了测试而不断公开,而不是因为类/层次结构/业务模型需要它公开。

第二个感觉也不对劲,因为任何 IDE 都找不到这个用例,因此任何搜索/替换/重构都会在这里失败。

所以我的问题是,是否应该使用第二种场景而不关心重构会破坏测试?或者甚至可能在断言中不鼓励使用一般常量?

unit-testing constants access-modifiers php-7.1

6
推荐指数
1
解决办法
2486
查看次数

C++ 中的 java“私有包”等效项是什么?

C++ 中的 java“私有包”等效项是什么?Java 包隐私功能(只有同一包中的类具有可见性)在提供 API 时非常有用。

C++ 是否有类似的功能(除了将其他类声明为“朋友”之外)?详细说明,例如假设 Ah 和 Bh 位于同一个包中(即 API lib)文件:Ah

class A
{
public :
void doA();

private : 
 int m_valueA;
};
Run Code Online (Sandbox Code Playgroud)

文件:Bh

class B
{
public : 
void doB()

private:
int m_valueB;

}
Run Code Online (Sandbox Code Playgroud)

我想要的是,

公共可见性:仅 A::doA() 和 B::doB()

在包内(即 API lib):A 应该能够访问 B::m_valueB 并且 B 应该能够访问 A::m_valueA。 不让彼此成为“朋友”课程。

c++ access-modifiers

6
推荐指数
2
解决办法
2409
查看次数

python中受保护变量和公共变量有什么区别

在Python中,类中的受保护变量和公共变量有什么区别

class A:
    def __init__(self):
        self._protected="protected"
        self.__private="private"
        self.public="public"

>>> a = A()
>>> a.public
'public'
>>> a._protected
'protected'
>>> 
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下其中的区别,并指导我如何在 python 中使用受保护的变量吗[如果我的方法用法是错误的]

提前致谢。

encapsulation class protected access-modifiers python-3.x

6
推荐指数
2
解决办法
4630
查看次数

(如何)我应该在 Vue.js 组件(TypeScript)中使用访问修饰符(公共、私有等)吗?

我有一个 Vue.js v2.6 项目,其中包含 TypeScript v.4.3“底层”。我的问题:我找不到任何可以澄清的文档,说明在Vue 组件
中 使用是否有意义以及如何正确使用它们。 我搜索了文章、Vue.js 文档和 StackOverflow,但没有任何发现。(Vue.js 文档完全忽略了它们的存在!)access modifiers

这就是我目前在 Vue 组件中使用访问修饰符的方式:

myComponent.vue 的模板部分:

<template>
  <div>
    <!-- accessing some of the fields of the class here e.g. the getter -->
  </div>
</template>
Run Code Online (Sandbox Code Playgroud)

myComponent.vue 的脚本部分:

<script lang="ts">
  import { Vue, Component, Prop, Emit } from "vue-property-decorator";

  @Component()
  export default class MyComponent extends Vue {
    @Prop() public readonly myPropertyVariable!: boolean;

    public myVariable!: string; // accessed in template

    private myInternalVariable!: boolean; // not accessed …
Run Code Online (Sandbox Code Playgroud)

access-modifiers typescript vue.js vuejs2 vue-class-components

6
推荐指数
1
解决办法
3261
查看次数

您是否有理由无法在方法或界面中定义访问修饰符?

方法可见性的责任归结为实现接口的类.

public interface IMyInterface
{
  bool GetMyInfo(string request);
}
Run Code Online (Sandbox Code Playgroud)

在方法GetMyInfo()生成以下错误之前,在C#set访问修饰符public,private或protected中:修饰符'private'对此项无效.

您是否有理由无法在方法或界面中定义访问修饰符?

(问题已经在法语中提到了这里)

c# interface access-modifiers

5
推荐指数
2
解决办法
2591
查看次数

我在哪里可以阅读有关D类访问修饰符的更多信息?

我似乎无法为D编程语言类访问修饰符找到一个很好的参考.

我知道public并且private非常有保证,但我猜还有更多,我似乎无法找到一个很好的信息来源.

有人能指点我好参考吗?

d access-modifiers

5
推荐指数
1
解决办法
333
查看次数

访问Eclipse项目共享的类中的包私有字段

我有一个模型类(MVC模式),我在两个Eclipse项目中使用.

我们称之为一个项目Producer是从流中捕获数据并将其存储到数据库中.例如ObjectModel,所讨论的模型类用于在序列化和存储在db中之前反序列化流以进行操作.

我们称之为另一个项目Consumer是拉入存储在数据库中的数据并在屏幕上显示它.它使用相同的模型类来反序列化存储的数据,以便在可视化应用程序中使用.

我计划ObjectModel进入一个Eclipse项目,在项目ProducerConsumer项目之间共享源代码.但是,每个应用程序都具有当前位于同一程序包中的类,这些类利用了package-private访问修饰符来获取和设置字段ObjectModel.

有没有什么办法可以在多个Eclipse项目之间共享源代码并仍然使用共享源维护包私有访问?

更新:我在Eclipse项目中共享代码时遇到了问题,这就是为什么我不会在发布之前尝试这个.最后得到了那部分工作,并将其作为另一个答案写在这里.

java eclipse access-modifiers shared-libraries package-private

5
推荐指数
1
解决办法
920
查看次数

我需要一个java方法,可以从我的API中的任何地方访问,但无法使用API​​从应用程序访问

我正在开发一个java API.在我的开发过程中,我一直面临以下问题:

我在两个不同的包中有两个类.包x中的A类,包y中的B类.我需要类A来访问类B中定义的方法M.因此,应该用于方法M的修饰符是public.但是,我不想让在他/她的java应用程序中使用我的API的开发人员访问方法M.问题是方法M有一个public我提到的修饰符,因此任何人都可以在API中访问它或来自API之外.同时,如果我将方法M的修饰符级别降低到protectedprivate,则类A将无法访问方法M,因为它属于不同的包.我怎么解决这个问题?我唯一的解决方案是在同一个包中有A和B吗?

java api methods access-modifiers modifier

5
推荐指数
1
解决办法
553
查看次数