C Sharp 中的“朋友”关键字相当于什么?
如何使用“内部”关键字?
我读过'internal'关键字是C#中'friend'的替代品。
我在我的 C# 项目中使用了一个 DLL,我有它的源代码,但我不想修改现有代码。我继承了这个类,我可以以任何我想要的方式使用我继承的类。问题是父类中的大部分代码都有受保护的方法。使用朋友是否可以访问或调用这些受保护的方法?
C Sharp 中的“朋友”关键字相当于什么?
如何使用“内部”关键字?
我读过'internal'关键字是C#中'friend'的替代品。
我在我的 C# 项目中使用了一个 DLL,我有它的源代码,但我不想修改现有代码。我继承了这个类,我可以以任何我想要的方式使用我继承的类。问题是父类中的大部分代码都有受保护的方法。使用朋友是否可以访问或调用这些受保护的方法?
您可以使用关键字访问修饰符internal
将类型或类型成员声明为只能由同一程序集中的代码访问。
您可以使用 中InternalsVisibleToAttribute
定义的类将System.Rutime.CompilerServices
类型声明为同一程序集中的代码或仅指定程序集中的代码可访问。
您使用第一个,因为您使用任何其他访问修饰符,例如private
. 以机智:
internal class MyClass {
...
}
您使用第二个如下:
[assembly:InternalsVisibleTo("MyFriendAssembly", PublicKey="...")]
internal class MyVisibleClass {
...
}
这两者都可以正确地视为friend
C# 中的等价物。
protected
派生类已经可以使用的方法。
不,“内部”与“朋友”不同(至少是 C++ 的“朋友”)
朋友指定这个类只能由一个特定的类访问。
internal 指定该类可由程序集中的任何类访问。
internal
正如您所猜测的那样,是 VB.NET 关键字的 C# 等效项friend
(而不是替换)
用法如下
internal void Function() {}
internal Class Classname() {}
internal int myInt;
internal int MyProperty { get; set; }
基本上,它是一个访问修饰符,它规定标记为内部的类/函数/变量/属性的可访问性就好像它对编译它的程序集是公共的,而对任何其他程序集都是私有的
您的子类将能够访问您继承的类的受保护成员。
您是否希望将这些受保护成员的访问权限授予另一个类?
这是我用来添加类似于 C++friend
关键字的行为的奇怪技巧。这仅适用于嵌套类 AFAIK。
protected
或接口。private
这是 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
}
}
我认为这只适用于嵌套类。如果您想对常规类执行此操作,则需要将它们嵌套在部分外部类中,这在理论上应该可以工作,并使用一个protected
或private
嵌套接口(或两个,如果您愿意)为它们提供访问权限对彼此的私人... 出来错了。
内部相当于朋友。受保护的方法仅在同一类中或从继承者中可用。如果您试图从继承者公开受保护的方法,您可以将它们包装在公共方法中。
将一个大类拆分为两个部分类文件可以实现所需的朋友效应。它不等效,但在某些情况下有效。