Use internal class as T in List<T> - c#

Code:
Assembly with internal class (Example class)
internal class Abc
{
int a;
float pos;
}
How do i make a List<T> with T as internal class Abc?
It's an external assembly which means that I can't do InternalsVisibleTo, and the assembly isn't made by me so I can't just edit it.

I think the List<T> issue is a moot point. Really what you seem to be asking is "how do I expose an internal implementation to a public API?"
There are a few options for this:
Use an interface (if implementations are related by functionality)
Use an abstract class (if derived types are related by identity)
Use a base class (if derived types are related by identity and the base class may also be instantiated)
Example
Consider AbcBase and AbcInternal are in a separate assembly.
// Provides a publicly available class.
// Note, the internal default constructor will only allow derived types from the same assembly, meaning the class is essentially sealed to the outside world
public class AbcBase
{
internal AbcBase()
{
}
protected int a;
protected float pos;
public static List<AbcBase> CreateList()
{
return new List<AbcBase>()
{
new AbcInternal(1, 2.3f),
new AbcInternal(4, 5.6f)
};
}
}
internal sealed class AbcInternal : AbcBase
{
public AbcInternal(int a, float pos)
{
this.a = a;
this.pos = pos;
}
}
Consider Program is in the consuming assembly, or in other words, references the assembly where AbcBase and AbcInternal are implemented
class Program
{
static void Main(string[] args)
{
List<AbcBase> list = AbcBase.CreateList();
}
}
Note that the public implementation is exposed through AbcBase but not the internal implementation.
public class AbcImpl : AbcBase
{
}
Note, the above will cause a compiler error because the contructor in AbcBase is internal, therefore this class cannot be overridden from a different assembly.
'AbcBase.AbcBase()' is inaccessible due to its protection level

Provided you have a variable of the type Abc you can do the following:
// Get the value of type Abc with its runtime type.
var abc = ...;
// Variable listOfAbcs will be of type List<Abc>.
var listOfAbcs = CreateList(abs);
// Local function to create a list.
List<T> CreateList<T>(T value) => new List<T>();
Alternatively you can create a list with reflections and access it via IList interface.

You can't. internal restricts access to the type to only the containing assembly.

Related

Understanding Access specifiers on Classes in C#

First of all let me start by saying that I do understand access specifiers I just don't see the point of using them in classes. It makes sense on methods to limit their scope but on classes, why would you want a private class, isn't it the purpose of classes to be able to reuse them?
What is the purpose of access specifiers when declaring a class in C#? When would you use them?
Thanks
Well, let's say that you want a class to be only accessed inside her own assembly:
internal class Test
Let's say that you have two classes, one inside the other (nested classes):
protected internal class TestA
{
private TestB _testB;
private class TestB
{
}
public TestA()
{
_testB = new TestB();
}
}
The TestB class can be only accessed inside methods/properties/contructors inside TestA or inside herself.
The same applies to the protected modifier.
// Note
If you don't specify the access modifier, by default it will be private, so on my example the following line:
private TestB _testB;
is equal to
TestB _testB;
And the same applies to the class.
Special Modifier
Then, there is the protected internal which joins both modifiers so you can only access that class inside the same assembly OR from a class which is derived by this one even if it isn't in the same assembly. Example:
Assembly 1:
public class TestA : TestB
{
public TestB GetBase()
{
return (TestB)this;
}
public int GetA1()
{
return this.a1;
}
}
protected internal class TestB
{
public int a1 = 0;
}
Program
TestA _testA = new TestA(); // OK
TestB _testB = new TestB(); // ERROR
int debugA = new TestA().a1 // ERROR
int debugB = new TestA().GetA1(); // OK
TestB testB_ = new TestA().GetBase(); // ERROR
Source
Link (Access Modifiers)
Internal
The type or member can be accessed by any code in the same assembly,
but not from another assembly.
Private
The type or member can be accessed only by code in the same class or
struct.
Protected
The type or member can be accessed only by code in the same class or
struct, or in a class that is derived from that class.
Public
The type or member can be accessed by any other code in the same
assembly or another assembly that references it.
I will give you an example of an internal class. Imagine I have some DLL. Form this DLL I want to expose only a single class called A. This class A however, should have access to other classes inside DLL - thus I will make all other classes inside DLL internal. Hence, from the DLL you can only use class A, while A can still access other classes inside DLL - you however, can't.
The greatest benefit of using access specifiers is when someone else is using your classes. By clearly specifying, what should and what should not be touched within your objects, you can protect your object internal mechanism and integrity from being misused or damaged.
With bigger classes, if you made everything public, you would also make it harder for the user of your code to work with IntelliSense, which is something that is very handy when you deal with unknown libraries.
I have created one application to understand Access Specifiers.
It will be more easy to understand it with code instead of Theory.
I have added my notes in code, for better guidance.
namespace ConsoleApplication1
{
//A normal public class which contains all different types of access-modifier classes in the assembly named 'ConsoleApplication1'
public class Base
{
public class PublicBase
{
public static void fn_PublicBase()
{
Console.WriteLine("fn_PublicBase");
}
}
private class PrivateBase
{
public static void fn_PrivateBase()
{
Console.WriteLine("fn_PrivateBase");
}
}
protected class ProtectedBase
{
public static void fn_ProtectedBase()
{
Console.WriteLine("fn_ProtectedBase");
}
}
internal class InternalBase
{
public static void fn_InternalBase()
{
Console.WriteLine("fn_InternalBase");
}
}
protected internal class ProInternalBase
{
public static void fn_ProInternalBase()
{
Console.WriteLine("fn_ProInternalBase");
}
}
//TIP 1:This class is inside the same class 'Base' so everything is accessible from above.Hurray!!
class Base_Inside
{
public static void fn_Base_Inside()
{
//All methods are easily accessible.Does not consider a modified indeed.
PublicBase.fn_PublicBase();
PrivateBase.fn_PrivateBase();
ProtectedBase.fn_ProtectedBase();
InternalBase.fn_InternalBase();
ProInternalBase.fn_ProInternalBase();
}
}
}
//Different class but inside the same assembly named 'ConsoleApplication1'
public class Base_Sibling : Base
{
//TIP 2:This class is NOT in same class 'Base' but in the same assembly so only protected is NOT accessible rest all are accessible.
public void fn_Base_Sibling()
{
PublicBase.fn_PublicBase();
//PrivateBase.fn_PrivateBase(); //ERROR:Accesibility of 'protected'
ProtectedBase.fn_ProtectedBase(); //protected is accessible because Base_Sibling inherit class 'Base'. you can not access it via Base.ProtectedBase
InternalBase.fn_InternalBase();
ProInternalBase.fn_ProInternalBase();
}
}
}
Now to Understand difference between internal, protected internal,
I Have added one for project named with Assembly_1 in same
solution.
I have inherited Base class of ConsoleApplication1 to Derived class of Assembly_1.
namespace Assembly_1
{
//TIP:if it does not inherit class 'ConsoleApplication1.Base' then we can not access any thing beacuse this is different assembly.
//TIP:only INTERNAL is NOT accessible , rest all are accessible from first assembly if it inherits class 'Soul'
public class Derived : ConsoleApplication1.Base
{
public class PublicDerived
{
public static void fn_PublicDerived()
{
PublicBase.fn_PublicBase(); //YES, becuase this is 'public'
//PrivateBase.fn_PrivateBase(); //No, becuase this is 'private'
ProtectedBase.fn_ProtectedBase(); //YES, becuase this is 'protected'
//InternalBase.fn_InternalBase(); //No, becuase this is 'internal'
ProInternalBase.fn_ProInternalBase(); //YES, becuase this is 'protected internal'
}
}
}
}
- Update answer 2019 -
Hi You can find accessibility via below table

C# implicit cast from base class to extended (System.Reflection.Assembly)

I've been working the project mentioned c-sharp-compilerresults-generateinmemory.
I've been writing a lot of code to get my "class discovery" implemented. It works cool, but I realized it would be a lot more efficient if I implemented everything as an derived class of `System.Reflection.Assembly'.
So with that new derived class written I hit a problem. When I try to assign the base class to the new derived class it throws an error, just the normal did you miss an explicit cast error.
I thought C# did implicit casting for extended types?
So I have some source code like this...
Assembly asm = MyCompilerResults.CompiledAssembly(); /* this works */
Interface asmInterface = new Interface();
asmInterface = asm; /* bad */
asmInterface = (Interface)asm; /* bad */
public class Interface : Assembly {
public Interface() {} // I always just declare the empty constructor.
public void Helpermethod1() {}
public void Helpermethod2() {}
public void Helpermethod3() {}
};
So as it's only the second week I've been writing C# I have to ask...
How do I add the base class to my class?
The question here... Why can't I write an implicit operator from a Base class to a Derived class in C#?
This seems to indicate my casting should work unless I'm misunderstanding the answers.
I think you missunderstood something. What you are trying to achieve is to assign base class to derived one. It's not possible on almost every case.
Consider following:
public class A
{
}
public class B : A
{
}
A a = new B();
// some code
B b = (B)a; // it is possible. Behind the scenes, variable a is of B type.
but:
A a = new A();
B b = (B)a; //IT'S NOT ALLOWED. The variable a is of type A that has
// no "knowledge" about B class.
In your case, CompiledAssembly() returns Assembly instance that has no any information about Interface class, so it cannot be directly casted.
There are two options. Write wrapper:
public class Interface
{
private readonly Assembly underlyingAssembly;
publiic Interface(Assembly asm)
{
this.underlyingAssembly = asm;
}
// other methods
}
Assembly someAsm = MyCompilerResults.CompiledAssembly();
Interface interface = new Interface(someAsm);
or write extension methods:
public static class AsmExt
{
public static void SomeMethod(this Assembly asm)
{
}
}
Assembly someAsm = MyCompilerResults.CompiledAssembly();
someAsm.SomeMethod();
You may want to acchieve something different here, which can be done by using extensionmethods
You have to create a static class which then offers the functionality to extend the object like this:
public static class AssemblyExtension
{
public static void HelperMethod1(this Assembly asm)
{
Console.WriteLine(asm.ToString());
}
}
You can then call it like this:
Assembly asm = MyCompilerResults.CompiledAssembly();
asm.HelperMethod1();

Using structs with generics - Inconsistent accessibility

I'm trying to use generics in inheritance with structs, see.
public class AuditLogEntry : ObjectBase<AuditLogEntry.AuditLogEntryStruct>
{
private struct AuditLogEntryStruct
{
public int AuditID;
}
}
public abstract class ObjectBase<T>
{
}
It won't let me use private for my struct, as it throws the error:
Inconsistent accessibility: base class 'ObjectBaseAuditLogEntry.AuditLogEntryStruct>' is less accessible than class 'AuditLogEntry'.
However I don't really want to make my struct public.
Any ideas?
Thanks,
Alex
Follow on question:
Here is what we are trying to do:
class AuditLogEntry : ObjectBase<AuditLogEntry.AuditLogEntryStruct>
{
internal struct AuditLogEntryStruct
{
public int AuditID;
}
public int AuditID
{
get
{
return udtObject.AuditID;
}
set{
BeginEdit();
udtObject.AuditID = value;
}
}
class ObjectBase<T>
{
protected T udtObject;
protected T udtPreEditObject;
protected void BeginEdit()
{
if (!IsDirty)
{
IsDirty = true;
udtPreEditObject = udtObject;
}
}
}
I'm not sure how to achive this within making AuditLogEntryStruct public?
Thanks,
Alex
You can't derive a public class from a generic class when one or more of the type arguments aren't public
The types that any type derives from has to be as accessible as the deriving class, inculding any type parameters given as type arguments to the base class
if you have
public class publicClass{}
Any class can derive from A however if you changed it to
internal class internalClass{}
only other internal classes can derive from it.
The same is true if you passed either of the types as a type parameter. The first three below are valid the fourth is not
public class A : List<publicClass>{}
internal class B : List<internalClass>{}
internal class C : List<publicClass>{}
//not valid because D has wider accessibility than the close generic type List<internalClass>
public class D : List<internalClass>{}
EDIT
The language team at some point have had to make a decision whether to make a declaration as yours invalid or make any use of your type that resulted in illegal access to an inaccessible type invalid. In your case there would be several methods returning a type that would be inaccessible to all others than your class and a number of methods taking an argument of a type no other class could provide. So the only objects that would actually be able to use objects of your class would be objects of your class. You can solve that with composition instead of inheritance
public class AuditLogEntry
{
private ObjectBase<AuditLogEntry.AuditLogEntryStruct> _entry;
private struct AuditLogEntryStruct
{
public int AuditID;
}
}
public abstract class ObjectBase<T>
{
}
Consider this example:
public class Foo : List<Bar>
{
private struct Bar { }
}
var myFoo = new Foo();
...
var x = myFoo()[0]; // expression on the right side is of type Bar, yet Bar is inaccessible
UPDATE
What you are trying to achieve doesn't really require generics. You only access your structs inside ObjectBase<T> as if they were objects. You might as well change them to object and remove generic type altogether.
If you have some more logic that requires some sort of functionality from AuditLogEntryStruct to be accessable in ObjectBase<T>, you may extract an interface:
public interface IStructsWithSomeFunctionality { ... }
make your struct implement it and use it as your type parameter
public class AuditLogEntry : ObjectBase<IStructsWithSomeFunctionality> { ... }

What is an internal sealed class in C#?

I was looking through some C# code for extending language support in VS2010 (Ook example). I saw some classes called internal sealed class
What do these do? Would one use them?
It is a class that:
internal: Can only be accessed from within the assembly it is defined (or friend assemblies).
sealed: Cannot be inherited.
Marking classes as internal is a way of preventing outside users of an assembly from using them. It's really a form of design encapsulation and IMHO it is good practice to mark types that are not part of the intended public API\object models as internal. In the long term this prevents users of your library from coupling themselves to types which you did not intend them to. This sort of unintended coupling harms your ability to change and evolve the way your libraries are implemented as you cannot change them without breaking your clients. Using internal helps to keep the public and usable surface area of a library down to what is intended.
Marking classes as sealed prevents these classes from being inherited. This is a pretty drastic design intent which is sometimes useful if a class is already so specialized that it is sensible that no other functionality should be added to it via inheritance either directly or via overriding its behaviour.
internal and sealed modify types in quite different ways, but they can be used together.
NB You have some further scoping control of internal as you can define a set of other assemblies as 'friends'. These friend assemblies may access your internal types. This can be useful for defining sets of co-operating assemblies such as production and test assemblies. It is often desirable that a test assembly can see all the types in the assembly it is testing.
internal: A class which can only be accessed inside the same assembly.
Assembly1.dll:
namespace test {
internal class InternalClass {
}
public class PublicClass {
}
}
Assembly2.dll:
using test;
...
InternalClass c1; // Error
PublicClass c2; // OK
sealed: A class which cannot be derived from
sealed class SealedClass { ... }
class ChildClass : SealedClass {} //ERROR
Internal means the member is accessible to other types that are defined in the same assembly. A Sealed class is sort of the oppositie of abstract. It can be instantiated but cannot serve as a base class. The primary reason to seal a class is to prevent your users from fiddling around with it and breaking it. It’s also the case that sealing a class permits certain compiler optimizations that are not possible with non-sealed classes.
An internal sealed class is one that is:
internal - Only accessible from within the same assembly
sealed - Cannot be subclassed
In other words, there's no way for you to use it directly.
Internal means it can be used only in same assembly,
The internal keyword is an access
modifier for types and type members.
Internal types or members are
accessible only within files in the
same assembly
sealed that can't be inherited
A sealed class cannot be inherited. It
is an error to use a sealed class as a
base class. Use the sealed modifier in
a class declaration to prevent
inheritance of the class.
INTERNAL
Internal types or members are accessible only within files in the same assembly.
Example
// Assembly1.cs
// Compile with: /target:library
internal class BaseClass
{
public static int intM = 0;
}
// Assembly1_a.cs
// Compile with: /reference:Assembly1.dll
class TestAccess
{
static void Main()
{
var myBase = new BaseClass(); // compile error
}
}
SEALED
First of all, let's start with a definition; sealed is a modifier which if applied to a class make it non-inheritable and if applied to virtual methods or properties makes them non-ovveridable.
public sealed class A { ... }
public class B
{
...
public sealed string Property { get; set; }
public sealed void Method() { ... }
}
An example of its usage is specialized class/method or property in which potential alterations can make them stop working as expected (for example, the Pens class of the System.Drawing namespace).
...
namespace System.Drawing
{
//
// Summary:
// Pens for all the standard colors. This class cannot be inherited.
public sealed class Pens
{
public static Pen Transparent { get; }
public static Pen Orchid { get; }
public static Pen OrangeRed { get; }
...
}
}
Because a sealed class cannot be inherited, it cannot be used as base class and by consequence, an abstract class cannot use the sealed modifier. It's also important to mention that structs are implicitly sealed.
Example
public class BaseClass {
public virtual string ShowMessage()
{
return "Hello world";
}
public virtual int MathematicalOperation(int x, int y)
{
return x + y;
}
}
public class DerivedClass : BaseClass {
public override int MathematicalOperation(int x, int y)
{
// since BaseClass has a method marked as virtual, DerivedClass can override it's behavior
return x - y;
}
public override sealed string ShowMessage()
{
// since BaseClass has a method marked as virtual, DerivedClass can override it's behavior but because it's sealed prevent classes that derive from it to override the method
return "Hello world sealed";
}
}
public class DerivedDerivedClass : DerivedClass
{
public override int MathematicalOperation(int x, int y)
{
// since BaseClass has a method marked as virtual, DerivedClass can override it's behavior
return x * y;
}
public override string ShowMessage() { ... } // compile error
}
public sealed class SealedClass: BaseClass {
public override int MathematicalOperation(int x, int y)
{
// since BaseClass has a method marked as virtual, DerivedClass can override it's behavior
return x * y;
}
public override string ShowMessage()
{
// since BaseClass has a method marked as virtual, DerivedClass can override it's behavior but because it's sealed prevent classes that derive from it to override the method
return "Hello world";
}
}
public class DerivedSealedClass : SealedClass
{
// compile error
}
Microsoft documentation
Sealed: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/sealed
Internal: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/internal

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

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?
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 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.
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.
internal is the C# equivalent of the VB.NET friend 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
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?
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 or private 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.
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.
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.

Categories