Class-member access-modifiers - c#

I want a method of the class: "One" ("AccessibleWithinSameNamespace") to be accessible by the class: "Two", without having "Two" extending "One".
Both classes are in the same namespace, so I'm thinking that maybe there's an access-modifier that emulates the "protected" modifyer, but for namespaces.
Some code:
namespace Test
{
class One
{
public void AccessibleToAll()
{
}
protected void AccessibleWithinSameNamespace()
{
// I am not public
// I can be accessed from other classes
// within the same namespace of my class
}
}
}
namespace Test
{
class Two
{
public Two()
{
One one = new One();
// I am able to access this method because my class
// is in the same namespace as the class: "One"
one.AccessibleWithinSameNamespace();
}
}
}

You can use the internal modifier if both classes are in the same assembly.
With your example:
namespace Test
{
class One
{
public void AccessibleToAll()
{
}
internal void AccessibleWithinSameNamespace()
{
// I am not public
// I can be accessed from other classes
// within the same namespace of my class
}
}
}
namespace Test
{
class Two
{
public Two()
{
One one = new One();
// I am able to access this method because my class
// is in the same namespace as the class: "One"
one.AccessibleWithinSameNamespace();
}
}
}

C# and .NET have no concept of "within the same namespace". Internal is the closest equivalent.

The problem isn't the access modifier for the namespace its the access modifier for the function. "Protected" means that it can be accessed by child classes, not by other classes even if they're in the same namespace.
You have several solutions to choose from...
1. you can make the access modifier for the function "internal" then all classes/functions inside the same assembly (or marked with some cool assembly flags so that they pretend to be in the same assembly) can access it
2. Make "TWO" a sub class of "One" then two can call into it (but not via an instance of "One" as shown in the same code

Since namespaces are arbitrary - they can't really be a security boundary. Anyone can create an assembly that reuses your namespace Test.
The best you can do is limit by assembly using the already mentioned internal (and InternalsVisibleTo if needed).
Edit: InternalsVisibleTo allows other assemblies to access internal methods and classes as if they were in the same assembly. You can strong name the other assemblies, which provides security. This is commonly used for test assemblies to test internal members of the main assembly, without bloating the main assembly by including the test code.
Note that, the VB.NET compiler does not respect InternalsVisibleTo - so a VB assembly cannot call into an InternalsVisibleTo attributed assembly. However, C# can call into a VB.NET assembly that has the appropiate InternalsVisibleTo attribute.

Related

Internal class visible from another namespace in Unity project

I am organizing my unity project into namespaces, and want to hide the classes that are used only inside the namespaces.
I define the namespace MyProject.Accounts and place an internal class there:
namespace ProjectName.Accounts
{
internal struct PictureData
{
internal int notSeenMember;
}
}
Then i add the using ProjectName.Accounts to a file in ProjectName.LoginScreen namespace, and i am able to see the class through the Intellisence, and instanciate it, but not to use the notSeenMember member:
The MS says that :
Internal types or members are accessible only within files in the same assembly.
Is being able to instanciate internal classes from other namespaces an expected behavior?
EDIT: you can also access the internal members

Cannot access internal classes outside of DLL & certain public variables aren't accessible

I'm having a hard time making this work.
The 3 classes FooType, WebApp & IWebApp must not be accessbile \ visible outside of this DLL. So hence the sealed & internal classes.
Issues I'm having are ...
1) In WebApp class, FeeType1 is not accessible in RouteOneBuilder method's parameter.
2) In WebApp class, FeeType1 is not accessible \ visible in switch's case-statement. (need to be visible).
3) In WebApp class, CreditApplication of FeeType1 property is not visible in the switch's case-statement (need to be visible).
Is there a better way to this complicated script? Am I already screwed for exposing classes outside of this DLL? Can all of step 1 to 4 be resolved differently (or be fixed somehow)?
I don't see how can I make this any simplier.
internal static class FooType
{
public class FeeType
{
public FeeType() { }
public string CreditApplication = "Credit Application";
public string CreditVehicle = "Credit Vehicle";
}
public FeeType FeeType1
{
get { return new FeeType(); }
private set { }
}
}
sealed class WebApp : IWebApp
{
public string RouteOneBuilder(FooType.FeeType1 typing)
{
var xml = "";
switch(typing)
{
case FooType.FeeType1.CreditApplication:
xml = "asdf";
break;
default:
throw new Exception("Unknown value");
}
return xml;
}
}
internal interface IWebApp
{
string RouteOneBuilder(FooType.FeeType typing);
}
Your definition of a sealed class is incorrect. It is not an access modifier like public, private, protected and internal. Marking a class sealed only says that it cannot be inherited from; it does not say anything about access per se.
From the MSDN documentation:
When applied to a class, the sealed modifier prevents other classes
from inheriting from it.
That means that you can still provide a public class that is sealed. However, if you try to inherit from a sealed class, you will receive a compiler error like this:
cannot derive from sealed type 'YourNamespace.YourSealedClass'.
Also, I suggest you read this and this regarding internal/public and nested classes.
Now, looking at the code you provided, the following compiler errors pop up:
FooType.FeeType1': cannot declare instance members in a static class
This error means that if the class is declared static, all of the members must be static too.
FooType.FeeType1' is a 'property' but is used like a 'type'
This arises from the fact that the class is static but none of the members are.
Inconsistent accessibility: parameter type 'FooType.FeeType' is less
accessible than method 'IWebApp.RouteOneBuilder(FooType.FeeType)'
The return type and each of the types referenced in the formal parameter list of a method must be at least as accessible as the method itself.
You can find more information about the last error here.
The design is not correct.
If a type is marked as internal this indicates that it should never be accessed outside of its DLL. If this type must be accessed outside of the DLL in which it is declared, it should not be marked internal.
What constraint is preventing you from using a public modifier or from including the types in the same DLL as the consuming code?
In certain cases it is useful for external DLLs or EXEs to view internal members declared in another DLL. One notable case is for unit testing. The code under test may have an internal access modifier, but your test DLL still needs to access the code in order to test it. You can add the following to AssemblyInfo.cs of the project containing the internal members to allow external access.
[assembly:InternalsVisibleTo("Friend1a")]
See InternalsVisibleToAttribute Class for more details.
Side note: The sealed access modifier doesn't prevent access from outside of the declaring DLL. It prevents other types from extending the type.

Can I break encapsulation/data hiding with namespaces (.Net)

If I am making a .Net dll, is it possible to break encapsulation in any program that uses it, by creating a class with the same namespace?
For example, consider a DLL with the following code in it:
using System;
namespace MyDLL
{
internal class MyClass
{
internal void Stuff()
{
...
}
}
}
If I was to then create a project, and reference the DLL, would I be able to do something like the following?
using System;
using MyDLL;
namespace MyDLL
{
public class TheirClass
{
MyClass exposedClass = new MyClass();
exposedClass.Stuff();
}
}
I'm currently working on a project that will have a few abstract classes I want a user to be able to inherit, but I only want to certain features to be exposed.
Thanks in advance.
No, using the same namespace have no impact on data encapsulation nor any impact on visibility (private/protected/internal). Namespaces are syntactic sugar in C#, actual class names consist of namespace, name and assembly identity.
So in your particular case adding class with full name MyDLL.TheirClass{TheirAssembly} will not make MyDLL.MyClass{MyDLL} visible from TheirClass (since your class is internal and new class is from other assembly not marked as InternalsVisibleTo in your assembly).

Why VS IDE gives error when we create private class

If we create private class under any namespace then we got compilation error but if we create private class as a nested class in another class then it compile fine. Another guy explained why we got an error for declaring private under any namespace ? He said:
Allowing classes to be private to a namespace would achieve no
meaningful level of protection.Any assembly in the world could simply
reference your dll, and start writing code in your namespace which
accesses your supposedly private classes.I think that's possibly the
answer you'd get from Microsoft.
I just really do not understand this sentence "start writing code in your namespace which accesses your supposedly private classes"
How can any one access my private class? Any can tell me this "start writing code in your namespace which accesses your supposedly private classes"
Suppose you have one DLL where you wrote:
// hypotetical code !
namespace My.Namespace
{
private class MyClass
{
}
}
By this you want to declare that this class can only be used withing the namespace My.Namespace. You want to make this class internal to that namespace and protect if form usage outside.
Now anyone could create a different DLL reference the above DLL and declare the same namespace My.Namespace and actually be able to use MyClass anyway. Because its in the same namespace:
// hypotetical code !
namespace My.Namespace
{
public class AnotherClass
{
private hisClass = new MyClass();
}
}
What use is the private modifier in this case?
Imagine the following scenario:
You write an assembly A.dll with a namespace Mou.MyStuff. In that namespace, there is a private class SomeClass. To whom should that class be visible, based on its private visibility? Only to other types in the same namespace?
Then, someone else can write his or her own assembly B.dll. In that assembly, they can define a class SomeOtherClass in namespace Mou.MyStuff. Nothing prevents them from using the very same namespace as you did, hence there would be absolutely no obstacle to accessing your "private" type.
If what you are looking for is visibility only within your assembly, use the internal visibility.

Can you create private classes in C#?

This is a question for the .NET philosophers:
It is my understanding that Microsoft consciously denied use of private classes in C#. Why did they do this and what are their arguments for doing so?
I, for example, am building a large application that includes a reporting tool. This tool uses a lot of business objects that are used only within the reporting tool and not in other parts of the project. I want to encapsulate them for use only within the reporting tool itself.
Great decision is creating separate project in VS for this tool, and I'll do like that, but I'm interesting, what if I can't do this - for exmple our architecture wasn`t good enough, and we have big single project.
Behind "private class" I mean a class that can't be used in any other namespace, except its own.
My question was not - how can I simulate this, or do in another way. I'm just wondering, why not use private keyword with class keyword without any parent classes. I`m thinking there should be some reason, and I want to know it
Allowing classes to be private to a namespace would achieve no meaningful level of protection.
Any assembly in the world could simply reference your dll, and start writing code in your namespace which accesses your supposedly private classes.
I think that's possibly the answer you'd get from Microsoft.
There's a workaround for this, but you might not like it.
Instead of using a namespace to scope your classes, use a public static partial class:
Before:
namespace MyCompany.Foo {
class Bar { }
public class Baz { }
}
After:
namespace MyCompany {
public static partial class Foo {
private class Bar { }
public class Baz { }
}
}
This construct, like a namespace, can span multiple files in the same project. But unlike a namespace, it cannot "escape" from your project (other projects cannot define other members inside Foo).
There's an added advantage that you can have utility methods that seem to have no class for code inside Foo.
The disadvantage is that, to use your non-private classes outside of your fake namespace, you have to reference them inside Foo:
using MyCompany;
// ...
var baz = new Foo.Baz();
This can be mitigated by using an alias for the class:
using Baz = MyCompany.Foo.Baz;
// ...
var baz = new Baz();
But you'd have to do it for each non-private class that you want to use.
UPDATE
It's interesting to note that C# 6 will have static using statements, which could effectively improve this proposal to use a public static partial class as a "module". You would just "use" the "module" to access its types directly.
Hopefully, it will work like this:
using MyCompany.Foo;
// ...
var baz = new Baz();
Just as if Foo was a namespace.
You can create a private class, as a member of another type:
public class Outer {
// ...
private class Inner {
// ...
}
}
and Inner is only visible to members of Outer.
At the outermost level (i.e. in a namespace) private as per its definition would not make sense (since there is nothing to be private in). Instead use internal (visible to the containing assembly's members only).
You can define a private class, but it can only be used by its containing class.
If you want a class that is only visible within a particular assembly (DLL/EXE/etc.), then you should declare it as internal (Friend in VB)
True but you can get a pretty close simulation of this with internal classes and the internalsvisibletoAttribute if the namespace is split across multiple assemblies.
Also remember that a class within another can be private to the outer class. The outer class can be considered a namespace for this purpose.
So I guess you want to do this
namespace Baz
{
private class foo
{
private int _bar;
}
}
If yes. Then what is the purpose foo will server. At namespace can you be more restrictive than internal , and make any use of the class.If I could do this where will I use this .
That is why you have this compile time validation.
Now Inside a Public Class it makes sense to have a private class. I cannot explain it better this Private inner classes in C# - why aren't they used more often?.

Categories