C Sharp中“朋友”关键字的等价物是什么?
如何使用'internal'关键字?
我已经读过“内部”关键字是C#中“朋友”的替代品。
我在我的C#项目中使用了一个DLL,我有源代码,但我不想修改现有的代码。我继承了这个类,我可以以任何我想要的方式使用我继承的类。问题是父类中的大多数代码都有受保护的方法。以某种方式使用朋友可以访问或调用这些受保护的方法吗?
答案 0 :(得分:34)
您可以使用关键字访问修饰符internal
将类型或类型成员声明为只能在同一个程序集中访问代码。
您可以使用InternalsVisibleToAttribute
中定义的System.Rutime.CompilerServices
类将类型声明为同一程序集或指定程序集中的代码可访问。
您在使用private
之类的任何其他access modifier时使用第一个。即:
internal class MyClass {
...
}
您使用第二个如下:
[assembly:InternalsVisibleTo("MyFriendAssembly", PublicKey="...")]
internal class MyVisibleClass {
...
}
这两个都可以正确地被认为是C#中的friend
。
protected
的方法已经可用于派生类。
答案 1 :(得分:30)
不,“内部”与“朋友”不一样(至少是C ++'朋友')
friend指定此类只能由ONE,特定类访问 internal指定程序集中的任何类都可以访问此类。
答案 2 :(得分:6)
1)Internal是VB.NET'friend'关键字的C#equivelant,正如您猜测的那样(而不是替换)
2)用法如下
internal void Function() {}
internal Class Classname() {}
internal int myInt;
internal int MyProperty { get; set; }
3)它基本上是一个访问修饰符,规定标记为internal的class / function / vairiable / property的可访问性就好像它是编译成汇编的程序集是公共的,并且对任何其他程序集是私有的
答案 3 :(得分:1)
您的子类将能够访问您继承的类的受保护成员。
您是否希望将这些受保护的成员访问另一个类?
答案 4 :(得分:0)
内部相当于朋友。受保护的方法仅在同一类或继承者中可用。如果您尝试从继承者公开受保护的方法,可以将它们包装在公共方法中。
答案 5 :(得分:0)
这是我用来添加类似于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
嵌套接口(或两个, (如果您愿意)向他们提供访问彼此私人的权限...错了。
答案 6 :(得分:0)
在两个部分类文件中分割一个大类可以达到所需的效果。它不是等效的,但在某些情况下可以使用。