What is the equivalent of a 'friend' keyword in C Sharp?
Solution 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.You can use the
InternalsVisibleToAttribute
class defined inSystem.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.
Solution 2
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.
Solution 3
internal
is the C# equivalent of the VB.NETfriend
keyword, as you have guessed (as opposed to a replacement)-
Usage is as follows
internal void Function() {} internal Class Classname() {} internal int myInt; internal int MyProperty { get; set; }
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
Solution 4
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?
Solution 5
Here's a weird trick I used for adding behaviour akin to C++'s friend
keyword. This only works for nested classes AFAIK.
- Create a nested
protected
orprivate
interface with the variables you'd like to give access to via properties. - Let the nested class inherit this interface and implement it explicitly.
- 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.
xarzu
Why Would I Use My Real Name When "Xarzu" Is so Cool? (I am not really 90 years old either) http://s3.envato.com/files/190523.jpg
Updated on May 03, 2020Comments
-
xarzu about 4 years
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?
-
Dave Cousineau over 6 yearsIt's not equivalent, but it is the mechanism by which a set of classes work together without exposing themselves to the rest of the world. It also encourages smaller modules and reduces 'spaghetti' relationships between classes.