3

Yeah, this question seems stupid. But how can I do that in C#? As we all know, it is easy for C++. If I have 10000000 members in one class, I need set the privilege one by one?

4
  • 3
    I do hope 10000000 members was an exaggeration for the purpose of illustration :) Commented Jul 31, 2015 at 9:48
  • 2
    I'm just going to leave this here... Single responsibility principle Commented Jul 31, 2015 at 9:49
  • 1
    If you need to modify a lot of source code manually, then ... use your programming skills. Write a tool (parser) or use already existing ones, which imply power of Regex or just your own custom algorithm to go through cs-files and set public for all members. Commented Jul 31, 2015 at 10:03
  • LoL, a class with 10000000 members is just a extreme example. :) Commented Aug 3, 2015 at 7:16

8 Answers 8

6

You can't do this in C#. The language requires each member to be individually set to public.

Incidentally, if you have a class with 10000000 members you all want to make public you have far bigger problems than the typing effort to do it.

Sign up to request clarification or add additional context in comments.

Comments

2

Each and every method and variable needs to have its own public declaration at the start. Sorry!

If you have a lot of methods that need changing, I'd recommend using find and replace.

Comments

0

If I have 10000000 members in one class

There's no such feature in C#, but anyway you shouldn't design classes with such number of members since you're breaking the single responsibility principle.

Properly design your classes, use a good separation of concerns and keep it simple (KISS) and you won't face the issue of having to turn thousands of members from one visibility to other one.

1 Comment

Just having many members does in no way even touche the single responsibility principle. it can even be the result of splitting responsibilities.
0

read class definition from the file where every member start with new line. then write a new file by appending every line with "public" you can achieve this. and just remove some unwanted public from file you have your desired class. see how to read and write a file in c# http://www.tutorialspoint.com/csharp/csharp_text_files.htm

Comments

0

Assuming you have som kind of class file, I would try to use RegEx (sorry, I can't provide example as I'm not good with RegEx)

Perhabs some plugins (for VS) have posibilities to do such operations (Resharper or similar)

1 Comment

Assuming their code is consistently formatted, the RegEx should be pretty straight forward. (If it’s not properly formatted, it’ll obviously require a touch more consideration.)
0

You cannot set the modifier of a class while runtime. If you're trying to set all the members of your type instance or get all of them.. use reflection. A simple example scenario would be..

You got a class..

public class MyFabulousClass { private object FabulousPropertyMember { get; set; } // and so on ... } 

And you want to set all its property members from type Object to a given value..

foreach (var member in typeof(MyFabulousClass).GetFields( BindingFlags.NonPublic ).Where(i => i.FieldType == typeof(Object))) { member.SetValue(instance, default(Object)); // do other stuff.. } 

That would set all non-public members to the default value for type Object

I don't know what you're trying to achieve but that would give you the ability to manipulate the values. Otherwise you would have to write your own runtime compiling thing which changes code while its runtime, but that would be very complex .

Comments

0

This is a short timesaver, but a timesaver nonetheless. Instead of going through and typing each public one by one, hold alt while you click in front of each member. This puts a cursor in each place you click. Once you have alt+clicked in front of every member you want to be public, type public followed by a space, just like you would in front of a single member. This way, you put public in front of all members in one fell swoop.

Comments

0

I had also an aesthetic problem and wrote a little source generator, so I now only have to put an attribute [GeneratePropertiesForAllPrivateVariables] and a partial before the class instead of repeating the public keyword endlessly.

It basically looks like this:

using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; using System; using System.Diagnostics; using System.Linq; using System.Text; namespace MemberAccess { [AttributeUsage(AttributeTargets.Class/* ToDo: | System.AttributeTargets.Struct */, AllowMultiple = false, Inherited = false)] public sealed class GeneratePropertiesForAllPrivateVariablesAttribute : Attribute { } [Generator] public class GeneratePropertiesForAllPrivateVariables : ISourceGenerator { public void Initialize(GeneratorInitializationContext context) { } public void Execute(GeneratorExecutionContext context) { #if DEBUG if (!Debugger.IsAttached) { // Debugger.Launch(); } #endif var classesWithAttribute = context.Compilation.SyntaxTrees .SelectMany(st => st.GetRoot() .DescendantNodes() .Where(n => n is ClassDeclarationSyntax) .Select(n => n as ClassDeclarationSyntax) .Where(r => r.AttributeLists .SelectMany(al => al.Attributes) .Any(a => a.Name.GetText().ToString() == "GeneratePropertiesForAllPrivateVariables"))); foreach (var declaredClass in classesWithAttribute) { if (declaredClass.Members.Count > 0) { // ToDo: Check for public partial class modifiers here string className = declaredClass.Identifier.ToString(); var generatedClass = this.GenerateClass(declaredClass); foreach (var classMember in declaredClass.Members) { // is field declaration? if (classMember.Kind().ToString() == "FieldDeclaration") { var fieldDeclaration = (classMember as FieldDeclarationSyntax); // and is private variable? if (fieldDeclaration != null && fieldDeclaration.Declaration is VariableDeclarationSyntax && classMember.Modifiers.Where(token => token.Text == "public").Count() == 0) { var variableDeclaration = fieldDeclaration.Declaration as VariableDeclarationSyntax; var declarator = variableDeclaration.DescendantNodes().Where(n => n is VariableDeclaratorSyntax).First() as VariableDeclaratorSyntax; if (declarator != null) { string privateIdentifier = declarator.Identifier.ToString(); if (!string.IsNullOrEmpty(privateIdentifier)) { // strip possible 'private' modifier foreach (var modifier in classMember.Modifiers) if (modifier.Text == "private") classMember.Modifiers.Remove(modifier); // get uppercase identifier for public accessors string? publicIdentifier = null; if (char.IsLower(privateIdentifier[0])) publicIdentifier = privateIdentifier[0].ToString().ToUpper() + privateIdentifier.Substring(1); else if (privateIdentifier[0] == '_') publicIdentifier = privateIdentifier[1].ToString().ToUpper() + privateIdentifier.Substring(2); else if (privateIdentifier.Substring(0, 2) == "m_") publicIdentifier = privateIdentifier[2].ToString().ToUpper() + privateIdentifier.Substring(3); if (publicIdentifier != null) { // ToDo: didn't gigure out how to replace the private identifier with public one in the declarator // so using a hack with Sting.Replace in GeneratePropery :-/ this.GeneratePropery(ref generatedClass, classMember.ToString(), privateIdentifier, publicIdentifier); } } } } } } this.CloseClass(generatedClass); context.AddSource($"{GetNamespace(declaredClass)}_{className}.g", SourceText.From(generatedClass.ToString(), Encoding.UTF8)); } } } private StringBuilder GenerateClass(ClassDeclarationSyntax c) { var sb = new StringBuilder(); sb.Append(@" using System; using System.Collections.Generic; namespace "); sb.Append(GetNamespace(c)); sb.Append(@" { public partial class " + c.Identifier); sb.Append(@" {"); return sb; } private void GeneratePropery(ref StringBuilder builder, string declaration, /*FieldDeclarationSyntax fds,*/ string privId, string pubId) { string replaceIdentifier = declaration.Replace(privId, pubId); // ToDo: make sure that Replace only hits once -- or even better, find out string removeSemicolon = replaceIdentifier; // how to replace elements of a syntax and pass that as argument. if (removeSemicolon[removeSemicolon.Length - 1] == ';') removeSemicolon = removeSemicolon.Substring(0, removeSemicolon.Length - 1); string decl = $"public {removeSemicolon}"; string getter = $"get => {privId};"; string setter = $"set => {privId} = value;"; builder.AppendLine(@" " + decl + @" { " + getter + @" " + setter + @" }"); } private void CloseClass(StringBuilder generatedClass) { generatedClass.Append( @" } }"); } // determine the namespace the class/enum/struct is declared in, if any private string GetNamespace(BaseTypeDeclarationSyntax syntax) { // If we don't have a namespace at all we'll return an empty string // This accounts for the "default namespace" case string nameSpace = string.Empty; // Get the containing syntax node for the type declaration // (could be a nested type, for example) SyntaxNode? potentialNamespaceParent = syntax.Parent; // Keep moving "out" of nested classes etc until we get to a namespace // or until we run out of parents while (potentialNamespaceParent != null && potentialNamespaceParent is not NamespaceDeclarationSyntax && potentialNamespaceParent is not FileScopedNamespaceDeclarationSyntax) { potentialNamespaceParent = potentialNamespaceParent.Parent; } // Build up the final namespace by looping until we no longer have a namespace declaration if (potentialNamespaceParent is BaseNamespaceDeclarationSyntax namespaceParent) { // We have a namespace. Use that as the type nameSpace = namespaceParent.Name.ToString(); // Keep moving "out" of the namespace declarations until we // run out of nested namespace declarations while (true) { if (namespaceParent.Parent is not NamespaceDeclarationSyntax parent) { break; } // Add the outer namespace as a prefix to the final namespace nameSpace = $"{namespaceParent.Name}.{nameSpace}"; namespaceParent = parent; } } // return the final namespace return nameSpace; } } } 

Maybe this is heresy to C# purists, but works for me.

Note: The decorated class currently still needs to be public and non-static.

I also added a GitHub repo for your convenience.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.