什么相当于“朋友”? C Sharp 中的关键字?

发布于 2024-07-11 02:31:10 字数 243 浏览 11 评论 0原文

C Sharp 中的“friend”关键字相当于什么?

如何使用“内部”关键字?

我读到“internal”关键字是 C# 中“friend”的替代品。

我在我的 C# 项目中使用一个 DLL,我拥有该项目的源代码,但我不想修改现有代码。 我继承了该类,并且可以以任何我想要的方式使用我继承的类。 问题是父类中的大部分代码都有受保护的方法。 使用朋友是否可以以某种方式访问​​或调用这些受保护的方法?

What is the equivalent of a 'friend' keyword in C Sharp?

How do I use the 'internal' keyword?

I have read that 'internal' keyword is a replacement for 'friend' in C#.

I am using a DLL in my C# project that I have the source code for and yet I do not want to modify the existing code. I have inherited the class and I can use my inherited class any way I want. The problem is that most of the code in the parent class has protected methods. Will using a friend somehow make it possible to access or call these protected methods?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

请持续率性 2024-07-18 02:31:10
  1. 您可以使用关键字访问修饰符内部< /a> 将类型或类型成员声明为只能由同一程序集中的代码访问。

  2. 您可以使用InternalsVisibleToAttributeSystem.Rutime 中定义的类.CompilerServices 将类型声明为只能在同一程序集中或指定程序集中的代码访问。

您可以像使用任何其他访问修饰符(例如 私有。 也就是说:

internal class MyClass {
    ...
}

您可以按如下方式使用第二个:

[assembly:InternalsVisibleTo("MyFriendAssembly", PublicKey="...")]
internal class MyVisibleClass {
    ...
}

这两个都可以正确地视为 C# 中的 friend 的等价物。

保护的方法已可供派生类。

  1. You can use the keyword access modifier internal to declare a type or type member as accessible to code in the same assembly only.

  2. You can use the InternalsVisibleToAttribute class defined in System.Rutime.CompilerServices to declare a type as accessible to code in the same assembly or a specified assembly only.

You use the first as you use any other access modifier such as private. To wit:

internal class MyClass {
    ...
}

You use the second as follows:

[assembly:InternalsVisibleTo("MyFriendAssembly", PublicKey="...")]
internal class MyVisibleClass {
    ...
}

Both of these can rightly be considered the equivalent of friend in C#.

Methods that are protected are already available to derived classes.

吲‖鸣 2024-07-18 02:31:10

不,“内部”与“朋友”不同(至少是 C++ 的“朋友”),

朋友指定该类只能由一个特定类访问。
内部指定该类可由程序集中的任何类访问。

No, "internal" is not the same as "friend" (at least the C++ 'friend')

friend specifies that this class is only accessible by ONE, particular class.
internal specifies that this class is accessible by ANY class in the assembly.

涙—继续流 2024-07-18 02:31:10
  1. 内部 是 VB.NET friend 关键字的 C# 等效项(而不是替换)

  2. 用法如下

    内部 void Function() {} 
      内部类 类名() {} 
      内部 int myInt; 
      内部 int MyProperty { 获取;   放;   } 
      
  3. 它基本上是一个访问修饰符,规定标记为内部的类/函数/变量/属性的可访问性就好像它对程序集是公共的一样被编译,并且对任何其他程序集都是私有的

  1. internal is the C# equivalent of the VB.NET friend keyword, as you have guessed (as opposed to a replacement)

  2. Usage is as follows

    internal void Function() {}
    internal Class Classname() {}
    internal int myInt;
    internal int MyProperty { get; set; }
    
  3. It, basically, is an access modifier that stipulates that the accessibility of the class / function / variable / property marked as internal is as if it were public to the Assembly it is compiled in, and private to any other assemblies

活泼老夫 2024-07-18 02:31:10

您的子类将能够访问您继承的类的受保护成员。

您是否希望将这些受保护成员的访问权限授予另一个类?

Your subclass will be able to access the protected members of the class you inherit.

Are you looking to give access to these protected members to another class?

星星的軌跡 2024-07-18 02:31:10

这是我用来添加类似于 C++ 的 friend 关键字的行为的奇怪技巧。 这仅适用于嵌套类 AFAIK。

  1. 使用您想要通过属性授予访问权限的变量创建一个嵌套的 protectedprivate 接口。
  2. 让嵌套类继承此接口并显式实现它。
  3. 每当使用此嵌套类的对象时,请将其强制转换为接口并调用相应的属性。

这是来自 Unity 的示例。

using System;
using UnityEngine;
using UnityEngine.Assertions;

namespace TL7.Stats
{
    [CreateAssetMenu(fileName = "Progression", menuName = "TL7/Stats/New Progression", order = 0)]
    public class Progression : ScriptableObject
    {
        // Provides access to private members only to outer class Progression
        protected interface IProgressionClassAccess
        {
            CharacterClass CharacterClass { get; set; }
        }

        [System.Serializable]
        public struct ProgressionClass : IProgressionClassAccess
        {
            [Header("DO NOT EDIT THIS VALUE.")]
            [SerializeField] private CharacterClass characterClass;
            [Tooltip("Levels are 0 indexed.")]
            [SerializeField] float[] healthOverLevels;

            public float[] HealthOverLevels => healthOverLevels;

            CharacterClass IProgressionClassAccess.CharacterClass
            {
                get => characterClass;
                set => characterClass = value;
            }
        }

        static readonly Array characterClasses = Enum.GetValues(typeof(CharacterClass));
        [SerializeField] ProgressionClass[] classes = new ProgressionClass[characterClasses.Length];

        public ProgressionClass this[in CharacterClass index] => classes[(int)index];

        void Awake()
        {
            for (int i = 0; i < classes.Length; ++i)
            {
                // Needs to be cast to obtain access
                (classes[i] as IProgressionClassAccess).CharacterClass = (CharacterClass)characterClasses.GetValue(i);
            }
        }

#if UNITY_EDITOR
        public void AssertCorrectSetup()
        {
            for (int i = 0; i < characterClasses.Length; ++i)
            {
                CharacterClass characterClass = (CharacterClass)characterClasses.GetValue(i);
                Assert.IsTrue(
                    (this[characterClass] as IProgressionClassAccess).CharacterClass == characterClass,
                    $"You messed with the class values in {GetType()} '{name}'. This won't do."
                );
            }
        }
#endif
    }
}

我认为这只适用于嵌套类。 如果您想对常规类执行此操作,则需要将它们嵌套在部分外部类中,这在理论上应该有效,并使用 protectedprivate嵌套接口(或两个,如果你愿意的话)为他们提供对彼此隐私的访问......结果是错误的。

Here's a weird trick I used for adding behaviour akin to C++'s friend keyword. This only works for nested classes AFAIK.

  1. Create a nested protected or private interface with the variables you'd like to give access to via properties.
  2. Let the nested class inherit this interface and implement it explicitly.
  3. Whenever using an object of this nested class, cast it to the interface and call the respective properties.

Here's an example from Unity.

using System;
using UnityEngine;
using UnityEngine.Assertions;

namespace TL7.Stats
{
    [CreateAssetMenu(fileName = "Progression", menuName = "TL7/Stats/New Progression", order = 0)]
    public class Progression : ScriptableObject
    {
        // Provides access to private members only to outer class Progression
        protected interface IProgressionClassAccess
        {
            CharacterClass CharacterClass { get; set; }
        }

        [System.Serializable]
        public struct ProgressionClass : IProgressionClassAccess
        {
            [Header("DO NOT EDIT THIS VALUE.")]
            [SerializeField] private CharacterClass characterClass;
            [Tooltip("Levels are 0 indexed.")]
            [SerializeField] float[] healthOverLevels;

            public float[] HealthOverLevels => healthOverLevels;

            CharacterClass IProgressionClassAccess.CharacterClass
            {
                get => characterClass;
                set => characterClass = value;
            }
        }

        static readonly Array characterClasses = Enum.GetValues(typeof(CharacterClass));
        [SerializeField] ProgressionClass[] classes = new ProgressionClass[characterClasses.Length];

        public ProgressionClass this[in CharacterClass index] => classes[(int)index];

        void Awake()
        {
            for (int i = 0; i < classes.Length; ++i)
            {
                // Needs to be cast to obtain access
                (classes[i] as IProgressionClassAccess).CharacterClass = (CharacterClass)characterClasses.GetValue(i);
            }
        }

#if UNITY_EDITOR
        public void AssertCorrectSetup()
        {
            for (int i = 0; i < characterClasses.Length; ++i)
            {
                CharacterClass characterClass = (CharacterClass)characterClasses.GetValue(i);
                Assert.IsTrue(
                    (this[characterClass] as IProgressionClassAccess).CharacterClass == characterClass,
                    $"You messed with the class values in {GetType()} '{name}'. This won't do."
                );
            }
        }
#endif
    }
}

I think this only works for nested classes. In case you want to do this with regular classes, you'd need to nest them inside a partial outer class, which should work in theory, and use a protected or private nested interface (or two, if you're inclined) for providing them access to each other's privates... that came out wrong.

北座城市 2024-07-18 02:31:10

内部相当于朋友。 受保护的方法仅在同一类中或从继承者中可用。 如果您尝试从继承者公开受保护的方法,则可以将它们包装在公共方法中。

Internal is the equivalent of friend. A protected method is only available within the same class or from an inheritor. If you're trying to expose protected methods from an inheritor, you can wrap them in public methods.

你是暖光i 2024-07-18 02:31:10

将一个大类分成两个部分类文件可以达到所需的朋友效果。 它并不等效,但在某些情况下有效。

Splitting a big class in two partial class-files can achive the desired friend-effect. It is not equivalent, but it works in some cases.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文