Comments (15)
Most of the time, types in different namespaces are (and IMO should be) loosely coupled and a "namespace internal" access modifier would definitely help to achieve that.
from csharplang.
The CLR doesn't provide special accessibility like that. It only works from nested type back to parent type(s).
Also, the use of public nested types in this fashion is explicitly against the language design patterns:
https://msdn.microsoft.com/en-us/library/ms229027.aspx
It's more appropriate to define a public top-level interface and have a private nested implementation.
from csharplang.
It's more appropriate to define a public top-level interface and have a private nested implementation.
Could work though my use case would be for a struct so interface would box. Alternative would be for separate type and use internal
public class Thing
{
private ThingsThing _thing;
public ThingsThing MyThing => _thing;
}
public struct ThingsThing
{
public object Stuff { get; internal set; }
public void DoThings();
internal void DoThatThing();
}
But then it has assembly level visibility rather than class level 😿
from csharplang.
Maybe a assembly namespace level visibility would work, so internal
but scoped to namespace for tooling... edited
from csharplang.
Maybe a assembly namespace level visibility would work,
The CLR doesn't offer that form of accessibility either. At best the compiler could enforce it internally but the member would still be just internal
. Possibly a minor detail. There isn't a precedent of the C# compiler simulating an accessibility modifier that isn't offered by the CLR.
from csharplang.
An example use-case is Dictionary.Enumerator.ctor
and probably most strongly typed enumerators.
The constructor is internal
but its only meant to be used by Dictionary
not the rest of the assembly
from csharplang.
@benaadams In that case the type itself could be defined as private
.
from csharplang.
@alrz but then you can pass it back in a public function like public Enumerator GetEnumerator()
from csharplang.
@benaadams I see. This could use the IEnumerator
interface but to avoid boxing it didn't.
EDIT: However, you can't prevent calling default ctor in a value type anyways.
from csharplang.
Enforcing that an internal
constructor is only called in specific scenarios (e.g. within a parent or specific type) can easily be accomplished through a custom analyzer. I don't think it's really necessary to modify the language in order to support pseudo-accessibility modifiers.
from csharplang.
I would like to support this feature. And would like it to use only namespace
keyword instead of namespace internal
The usefulness of this is just like friend
in C++
And I think it should not need CLR support. Just compile time error
from csharplang.
I think many of the scenarios can be achieved with the new file-local types in C# 11, but I too really wish this were a feature! We now have assembly scoped types and file scoped types, now we just need namespace scoped types! :)
File scoped types dont work if you want to have the class be public but just the constructor be file/namespace scoped.
from csharplang.
For me the use case of internal namespace modifier allows for gradual separation of code into separate projects or NuGets.
Let's say I have some 100 services that all have the same structure: few public interfaces and models, IOC registration and the rest is completely internal to the service. In the end these services should really become NuGets but that requires:
- maintaining our private NuGet repository
- maintaining the project in a different GIT repository
- CI/CD pipelines
This requires too much time and work.
So the other option is to simply keep the services as different projects in the solution - which is what I'm doing now. 100 projects is not too many but the performance hit in Visual Studio is definitely there when opening or closing the solution.
But with internal namespaces?
I could have everything in a single project from the start, no need to suffer the performance hit with 100 projects. I can just have 100 folders in a single project. The "hidden internals" of my services would just stay hidden in its internal namespace.
//public part of the service
namespace SomeServiceNamespace
{
public interface ISomeService
{
Task DoStuffAsync();
}
}
//hidden part of the service
internal namespace SomeServiceNamespace.Internals
{
public class ServiceImplementation : ISomeService
{
public async Task DoStuffAsync()
{
//...
}
}
}
When there's enough resources (meaning development time and/or money) the code from internal namespaces can be moved not to a different project but to a completely different repository and become a NuGet in our local NuGet store with its own CI/CD.
from csharplang.
The "hidden internals" of my services would just stay hidden in its internal namespace.
Genuine question: what purpose does that "hidden internals" have within these services?
The reason I ask is that encapsulation to me means "stuff hidden away from the public eye". It's implementation details that I'm free to modify whenever I want without causing changes to the public API surface of my assemblies. Whether those implementation details are private or internal makes very little difference. If the thing exists in a class, I'll mark it private as that's what's available. If private didn't exist, I'd mark it internal and I'd really not care. It's all internal to the the assembly and so hidden away, it doesn't make any difference.
The only way this becomes a concern is if one steps onto the InternalsVisibleTo slippery slope. At that point internal stuff is now public too and so there's a need for a way of saying "really internal to" (which is the important part of this thread to me).
So what is the user case behind you wanting to hide some internal parts of an assembly from other parts? It all seems needlessly complicated to me.
from csharplang.
The "hidden internals" of my services would just stay hidden in its internal namespace.
Genuine question: what purpose does that "hidden internals" have within these services?
Say you want to have service interface ISomeService, it's some external dependency, whatever. You know it's gonna have at least two or three implementations. This is pretty normal in .NET MAUI when you are building something for multiple platforms. But also on backend when you mock your services for regression testing, etc.
Now you want to follow this convention for namespaces:
MyCompany.[MyProject].MyService.Interfaces
...or Abstract or Models, basically a library defining the contracts without implementation
Then
MyCompany.[MyProject].MyService.SomeImplementation
MyCompany.[MyProject].MyService.OthetImplementation
So what, right? This is what Microsoft normally does.
My options are:
- put everything in the runnable project. Yeah, that works of course.
The "ugly" thing is that SomeImplementation
can access OtherImplementation
and vice versa.
Of course you can use private classes but for that to work everything from a given implementation must be inside a private class of some other wrapper class which is also very ugly.
- so you create
MyCompany.[MyProject].MyService
project and put everything in there, including all implementations. That works too of course.
The problem persists. SomeImplementation
can access OtherImplementation
and vice versa. And now you also have additional csproj in your solution.
- or you create NuGets like everyone does
This is ideal solution but as I said in the post above, this requires too much work to set up.
With internal namespaces I could have nicer codebase with compiler checking that some implementations don't affect each other in any way.
Since it's just a matter of ugly/nice code it's probably not justified enough to be implemented...but I thought that about required properties as well :)
from csharplang.
Related Issues (20)
- [Proposal]: Extended identifier syntax
- [API Proposal]: IsNullableAttribute to flow nullability of generic type parameters into methods HOT 4
- Anonymous type optimization HOT 5
- Feature Request: Recursively Foreach
- [Proposal]: Relax `Add` requirement for collection expression conversions to types implementing `IEnumerable` HOT 2
- [Proposal]: Proposal for Allowing Single-Element Tuples in Type Definitions HOT 2
- [Proposal]: Params collections and older language versions HOT 1
- [Proposal]: Edit speclets to distinguish features already delivered from potential future enhancements HOT 3
- [Proposal]: `readonly` parameters in primary constructors for non-record types HOT 7
- [Issue]: Generic Type Specialization Not Working in C# HOT 38
- [Proposal]: AAAAAAAAAAAAAAAAAAAA
- Open questions for `field` and `value` as contextual keywords HOT 2
- Add collection literal support for `Memory<T>` and `ReadOnlyMemory<T>`. HOT 18
- Unexpected compiler behavior with records and implicit operators HOT 1
- YaoJunFeng
- Invalid implicit conversion from long to int HOT 6
- [Proposal]: Extending patterns to "as" HOT 19
- Proposal: Searched switch statement HOT 2
- [Proposal]: Allow `with` keyword for classes containing constructor expecting itself HOT 1
- [Proposal]: [Allow Custom Implicit Conversion from Struct to Nullable Struct] HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from csharplang.