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
Related
I have 1 interface IMetadata which i want to restrict access to only current assembly(class library) and not outside of that and hence I have marked it as internal.
Now I want to inject this interface to my base abstract class and call method of IMetadata on my base class method to perform some logic. Base class will receive versioning from derive class Type1 for instance hence i have marked base abstract class constructor as protected but I am getting below error :
Inconsistent Accessibility : Parameter type IMetadata is less
accessible than BaseType.BaseType(IMetadata)
But this metadata will always going to receive its concrete type from derive class(Type1) hence I want this base class constructor as protected and also I want Metadata to be only available in current assembly and not outside of it.
internal interface IMetadata
{
string CreateMetadata();
}
internal class Metadata : IMetadata
{
public Metadata(string location)
{
this.location = location;
}
public string CreateMetadata()
{
}
}
public interface IBaseType
{
Void Perform();
}
public abstract class BaseType : IBaseType
{
private readonly IMetadata _metadata;
protected BaseType(IMetadata metadata) //error
{
}
}
class Type1 : BaseType
{
public Type1(IMetadata metadata) :
base(metadata)
{
}
}
Can anybody tell me whats the problem and how do I achieve this encapsulation?
The reason the compiler performs these accessibility checks is to try to steer you into the "pit of success". You have "thingy" that you've marked (or allowed to default) as internal. That means it's an implementation detail within your assembly. Nothing outside of your assembly should know or care what this "thingy" is. It certainly won't be able to "say it's name" or create one.
You then write something that is public or protected. These are things which are visible to other assemblies. And then you're saying "in order to use this, you have to supply a thingy". You've leaked an implementation detail and that's why the compiler stops you. You need to look hard at this and either decide that it's not purely an implementation detail (and so make it public) or that you shouldn't be exposing it outside of your assembly.
Ideally you mark this constructor as private protected which carries the correct semantics - only the intersection of {classes inheriting from this class} and {classes within this assembly} can call it. Only other members of your assembly can get hold of the required instance anyway.
However, if you're not yet on C#7.2, you have to make a choice. I'd go with internal. It's an abstract class anyway, nobody can directly construct it even with a constructor that notionally isn't related to the inheritance hierarchy.
This compiles just fine and shows both approaches:
internal interface IMetadata
{
string CreateMetadata();
}
internal class Metadata : IMetadata
{
private readonly string location;
public Metadata(string location)
{
this.location = location;
}
public string CreateMetadata()
{
return string.Empty;
}
}
public interface IBaseType
{
void Perform();
}
public abstract class BaseType : IBaseType
{
private readonly IMetadata _metadata;
private protected BaseType(IMetadata metadata) //No error
{
}
internal BaseType(IMetadata metadata, int thing) //No error
{
}
public abstract void Perform();
}
class Type1 : BaseType
{
public Type1(IMetadata metadata) :
base(metadata)
{
}
public Type1(IMetadata metadata, int thing) : base(metadata, thing)
{
}
public override void Perform()
{
throw new NotImplementedException();
}
}
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.
What is the purpose of internal abstract method in a abstract class?
why to make an abstract method internal in a abstract class? if we want to restrict abstract class outside the assembly why don't we just make abstract internal class.
Is there any other logic behind it.
Adding internal member to a public abstract class makes it impossible to inherit that abstract class outside of assembly it was declared in. But the class itself as well as all derived classes can still be used (as the types are public) outside of declaring assembly.
Let's say you have an abstract class:
public abstract AMyClass
{
public string DoSomething()
{
return DoSomethingInternal();
}
internal abstract string DoSomethingInternal();
}
And another public class that inherits it, declared in the same assembly
public sealed MyClass : AMyClass
{
internal override string DoSomethingInternal()
{
return "Hey from MyClass!";
}
}
You could still create an instance of MyClass in different assemblies, but you won't be able to implement your own class that derives from AMyClass, because you won't be able to implement abstract DoSomethingInternal method.
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, as in this example
public class BaseClass
{
// Only accessible within the same assembly
internal static int x = 0;
}
Now in your case this is something like:
public abstract BaseClass
{
internal abstract void Print();
}
Now, in this case all the class which are in same assembly of BaseClass, will be able to override the Print method of BaseClass. But outside of the assembly classes will only be able to override public members. like
public abstract BaseClass
{
internal abstract void Print();
public abstract void Hello();
}
Classes outside of the assembly of BaseClass won't be able to use this class as one of member of this class is internal. Solution is create sub class in same assembly of BaseClass and use that class outside the assembly.
I suggest you to read the access modifier concept in c# from C# in depth by #john skeet.
Imagine you have a code in your project
lets say its a console app and we call it as ConsoleApplication1
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{}
}
public abstract class MyAbsClass
{
public string DoSomething()
{
return DoSomethingInternal();
}
internal abstract string DoSomethingInternal();
public abstract string DoSomethingExternal();
}
public class MyClass:MyAbsClass
{
internal override string DoSomethingInternal(){}
public override string DoSomethingExternal(){}
}
}
and now you have (lets say another consoleApp called ConsoleApplication2) you build your consoleapplication1 and add reference to it
using ConsoleApplication1;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
}
}
class NewClass : MyAbsClass
{
public override string DoSomethingExternal()
{
throw new NotImplementedException();
}
}
}
Now when you build this you get an error Error 1 'ConsoleApplication2.NewClass' does not implement inherited abstract member 'ConsoleApplication1.MyAbsClass.DoSomethingInternal()
Why this error?? because compiler is telling you that when you declare member as internal ,the class which is in the same assembly ie (ConsoleApplication1) can have access it.So no matter how many class you create in ConsoleApplication2 you wont be able to access it because it is declared internal.
Why can an abstract class not be sealed or static?
And I am also confused about the question Why declare static classes as sealed and abstract in C#?.
static class cannot be marked sealed because it is made sealed by compiler by default.
Static classes are sealed and therefore cannot be inherited.
static class cannot be marked as abstract, because it would be pointless. abstract class makes sense when you want all derived classes to implement same part of the logic. But because static class cannot be derived there is no way other class will implement these gaps.
They cannot inherit from any class except Object.
Both quotes from Static Classes and Static Class Members (C# Programming Guide).
C# specification is a little more detailed about that:
10.1.1.3 Static classes
A static class may not include a sealed or abstract modifier. Note, however, that since a static class cannot be instantiated or derived from, it behaves as if it was both sealed and abstract.
You can read what does it mean for class to be sealed or abstract:
An abstract class cannot be instantiated directly, and it is a compile-time error to use the new operator on an abstract class
The sealed modifier is used to prevent derivation from a class. A compile-time error occurs if a sealed class is specified as the base class of another class.
Update
And a word about an article linked in the query you mentioned (Static Class Design). It's already stated in accepted answer from that question. If you read carefully you can see that:
√ DO declare static classes as sealed, abstract, and add a private instance constructor if your programming language does not have built-in support for static classes.
.NET (so C# as well) do have built-in support for static classes, so you don't have (and even can't) to make your classes pseudo-static by marking it both sealed and abstract.
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 nonoverridable.
public sealed class A { ... }
public class B
{
...
public sealed string Property { get; set; }
public sealed void Method() { ... }
}
An example of its usage is to define a 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.
I have a user control that will handle images on a form. But depending on what the source is (web cam or ID scan or other video source) the user control is different.
But they share some common features so I want to create a base class.
My other controls all have some interface items that I need. I would like to declare the interface at the base level though and just implement at the class level. But virtual and override seems to be the closest way to get what I want. Is there any to do it, force the new class to implement the interface assigned at the base class? Looking around it look like making the class abstract (which I don't fully understand) might be a start. If it was just methods that might be alright, but I am also using properties. In that area I have hit a dead end in my searches for answers. Here is what I have so far. Am I on the right track? I just have not worked with abstract classes at all and only limited exposure to interfaces. From the research I think I have the method correct just not sure about the property.
public interface RequiredAnswer
{
void LabelRequiredFieldEmpty();
bool AnswerRequired{ get;}
}
public abstract partial class ExtImage : UserControl, RequiredAnswer
{
public virtual bool AnswerRequired
{
get
{
throw new NotImplementedException ("Answer Required");
}
}
public abstract void LabelRequiredFieldEmpty ()
{
//checkBox_AgreementAcceptedText.ForeColor = Color.Red;
}
So I would have a class
public partial class ExtImageWebCam : ExtImage
{
public override bool AnswerRequired
{
get
{
return valueFromThisClassThatMeansAnAnswerIsRequired;
}
}
public override void LabelRequiredFieldEmpty ()
{
// do something
}
}
When you declare a method abstract, you are basically saying that a child class must supply the definition of the method. You can make properties abstract. This sounds like it is exactly what you need.
Here is the MSDN article for further reference.
From MSDN
Properties
Abstract properties behave like abstract methods, except for the differences in declaration and invocation syntax.
It is an error to use the abstract modifier on a static property.
An abstract inherited property can be overridden in a derived class by including a property declaration that uses the override modifier.
Continuing later
In this example, the class DerivedClass is derived from an abstract class BaseClass. The abstract class contains an abstract method, AbstractMethod, and two abstract properties, X and Y.
abstract class BaseClass // Abstract class
{
protected int _x = 100;
protected int _y = 150;
public abstract void AbstractMethod(); // Abstract method
public abstract int X { get; }
public abstract int Y { get; }
}
Abstract base class with an Interface
An abstract class must provide implementation for all interface members.
An abstract class that implements an interface might map the interface methods onto abstract methods. For example:
interface I
{
void M();
}
abstract class C : I
{
public abstract void M();
}
First of all, interfaces should start with an I by convention, so your interface would be IRequiredAnswer.
Second, if you want to force the inherited classes to implement their own methods rather than inheriting them, just make them abstract in the base class:
public abstract class ExtImage : UserControl, IRequiredAnswer
{
public abstract bool AnswerRequired { get; }
public abstract void LabelRequiredFieldEmpty ();
}
Your child classes would then have to implement the method and property.
You're on the right track. Here's a simple example of what you could do. Making the Bar() method abstract forces the inheritors to implement it.
public interface IFoo{
void Bar();
}
public abstract class BaseFoo : IFoo
{
public abstract void Bar();
public void Implemented(){
Debug.WriteLine("this is a shared implementation");
}
}
public class KungFoo : BaseFoo{
public override void Bar()
{
}
}
You are on the right track for the creation of an interface and then defining an abstract class for your purpose.
Standard naming conventions for an interface has been broken however, interfaces are usually prefixed with an I to help identify them
public interface IRequiresAnswer
{
void LabelRequiredFieldEmpty();
bool AnswerRequired { get; }
}
I would also suggest changing the AnswerRequired property to a function as your concrete class says "do somthing to find result". Properties are usually meant to be quick, so performing any calculation within a property is masking that real work takes place when you call the property. With a function it is more apparent to callers that the result will not be achieved immediately.