Visual Studio auto generated code from gRPC .proto file - c#

I'm facing an issue where it seems that Visual Studio is changing the way objects look in a .proto file.
.proto file: concordium_p2p_rpc.proto
Example - this is in the .proto file:
message BlockHash {
string block_hash = 1;
}
After building my project I want to create an instance of this exact object, however, the property inside the object is now called "BlockHash_" and not "block_hash" as in the .proto file.
The confusion is complete if I try to serialize this object to JSON... Then the attribute is now called "blochHash"... a 3rd name.
So in .proto
{
"block_hash": ""
}
becomes in C#
BlockHash bh = new BlockHash()
{
BlockHash_: ""
}
and then when serialized
{
"blockHash": ""
}
What is with that?

OK, so I found the answer to this question myself in this article.
https://visualstudiomagazine.com/articles/2020/01/06/defining-grpc-messages.aspx
Why Microsoft decides to perform this renaming instead of just keeping the names are as they are in the .proto file, is beyond me and evidently it introduces problems that I don't see would have been there otherwise.
What happens is that Visual Studio wants to be the boss of what things are called, and therefore it wants to rename the attribute "block_hash" of the object BlockHash by making the first letter upper case, removing the underscore and making the first letter of the next word an upper case as well => "BlockHash".
However, since this is the name of the class itself, this name is probably problematic since class constructors use this name and therefore Visual Studio fixes it's own dodo be adding a tailing underscore, resulting in an attribute named "BlockHash_".
Why oh why do you do these things?!....

Related

What's the easiest way to create a managed visualiser in C#?

I have a background in C++ and recently I started working in C#.
I have written following pieces of code (in Visual Studio):
var list_Loads = database.GetData<Load>().ToList();
var test_list = list_Loads.Where(o => (o.Name.Substring(0, 3) == "123")).ToList();
When I run the program and I move my mouse over both lists, first I get the count, which is very useful, but when I ask for the entries, this is what I get:
0 : namespace.Load
1 : namespace.Load
2 : namespace.Load
...
Not very useful, as you can imagine :-)
So my question: how can I show the Name attributes of those objects?
I thought: no problem. I have a background in native visualisers, so it should be rather easy to turn this into useful information, but then it comes:
In order to alter the way that those objects are represented, there is the first proposal to add a [DebuggerDisplay] "tag" to the definition of that class in source code.
However, as those classes are part of a framework I'm just referring to, I don't have access to the source code and hence I can't modify this.
Then I found another solution, which comes down to: "Write an entire C# project, debug, test and install it and it might work" (see documentation on "Custom visualisers of data" on the Microsoft website).
I almost choked in my coffee: writing an entire project, just for altering the view of an object??? (While, in C++, you just create a simple .natvis file, mention the classname and some configuration, launch .nvload and that's it.
Does anybody know a simple way to alter the appearance of C# object, without needing to pass through the whole burden of creating an entire C# project?
By the way, when I try to load a natvis file in Visual Studio immediate window, this is what I get:
.nvload "C:\Temp_Folder\test.natvis"
error CS1525: Invalid expression term '.'
What am I doing wrong?
Thanks in advance
OP (my emphasis):
In order to alter the way that those objects are represented, there is the first proposal to add a [DebuggerDisplay] "tag" to the definition of that class in source code.
However, as those classes are part of a framework I'm just referring to, I don't have access to the source code and hence I can't modify this.
Does anybody know a simple way to alter the appearance of C# object, without needing to pass through the whole burden of creating an entire C# project?
If you just want to specify [DebuggerDisplay] on a type, you don't have to have access to the source code. You can make use of [assembly:DebuggerDisplay()] and control how a type appears in the debugger. The only downside is that [assembly:DebuggerDisplay()] naturally only affects the current assembly whose code your mouse is hovering over. If you wish to use the customised display in other assemblies that you own, then you must repeat the [assembly:DebuggerDisplay()] definition.
Here's an easy before-and-after example with DateTime. I picked DateTime because we generally don't have access to the source code and it has some interesting properties:
var items = new List<DateTime>
{
DateTime.Now.AddDays(-2),
DateTime.Now.AddDays(-1),
DateTime.Now
};
...which on my machine defaults to:
Maybe I'm fussy and I just want to see:
Day of the week and
Day of the year
...I can do that via:
using System.Diagnostics;
[assembly: DebuggerDisplay("{DayOfWeek} {DayOfYear}", Target = typeof(DateTime))]
...which results in:
Example:
namespace DebuggerDisplayTests
{
public class DebuggerDisplayTests
{
public DebuggerDisplayTests()
{
var items = new List<DateTime>
{
DateTime.Now.AddDays(-2),
DateTime.Now.AddDays(-1),
DateTime.Now
};
}
}
.
.
.
}
Overrides
[assembly:DebuggerDisplay()] can also be used as a means to override pre-existing [DebuggerDisplay] on a 3-rd party type. Don't like what style they have chosen? Is the type showing far too much information? Change it with [assembly:DebuggerDisplay()].

Is there a way in Visual Studio to check that for each enum defined in a c# project, all values specify their corresponding base type value?

This is kind of a bizarre question, but it's simply just a matter of checking things efficiently. As the title states, I would like to quickly check that all enums in a particular project have all their base type values specified. So for example, I might have:
public enum Animal
{
Bird = 0,
Cat = 1,
Dog = 2
}
This enum has its int base type values specified. If it were:
public enum Animal
{
Bird,
Cat,
Dog
}
then the base values would not have been specified.
Is there a way to either automatically check that this is the case for all enums, or quickly pull up all enums in the project via some Visual Studio search tool or other command and then manually check this is the case? I imagine the former option is not possible, so I guess the question boils down to: how do I pull up all classes with enums in my Visual Studio window?
The only way I know of enforcing this would be to use a code analyzer, such as fx-cop with a custom rule, or a static analyzer on Roslyn. Both options would require significant effort.
As for the 2nd part of your question:
how do I pull up all classes with enums in my Visual Studio window?
This should get you what you want for your 2nd option (with a slight change of a false positive).
From the main menu: Edit > Find and Replace > Find in Files
Find what: " enum " (notice the spaces)
Look in: Entire Solution.

How to use Resharper File/Live Templates to Generate Exception Class

I like to make a lot of custom exceptions for most error cases I run into, instead of say using InvalidOperation all the time.
I recently got Resharper and thought it's template functionality would be my savior, but I can't seem to get what I want out of the File/Live template function.
What I'm trying to do is essentially type this:
...
throw new [resharper key combo]MyCustomName[enter]
...
and get an exception class named 'MyCustomNameException' in file 'MyCustomNameException.cs'.
Live templates doesn't seem to be the right thing for me -- that expands code inline.
But file templates doesn't seem to either -- it only asks me to specify the name of the file. Is the file template option as close as I can get to what I want here?
Not sure about adding the 'Exception' part, but if you type the full name and press ALT + ENTER, ReSharper will offer to 'Create Class 'MyCustomNameException''. The code it creates is:
internal class MyCustomNameException : Exception
{
}

Is there a way to instruct visual studio to auto add fields at the bottom of the class instead of the top?

namespace Guilds
{
public class Wizard
{
public void Wear(IClothing clothing)
{
Console.WriteLine("Puts on the {Robe} and {WizardHat}".Fmt(clothing));
}
IClothing _clothes;
IWeapon _weapon; // <== I want my fields added at the bottom of the class!
}
}
I am aware that if you put your fields at the bottom, it will start adding subsequent ones to the bottom of the class as well. I would love to have this as the default behavior even for the first field.
This behavior is usually triggered when pressing Ctrl + . on top of an undeclared field.
Use Regionerate and create your own format template. it's free tool to use with visual studio.
Edit: You can also use CodeMaid because it seems that Regionerate and VS2012 do not work together (I have not tested that combination at all though. I have VS2010)
Edit Adding more to my previous reply. CodeMaid is really cool and you can specify the layout in configuration. Also in configuration, you can specify that file should be formatted on save. This way write your code in anyway you want and have it formatted when you press Ctrl+S! I am one happy user of CodeMaid. Also I am using Visual Studio 2013.

Visual Studio Text Editor Extension

I am trying to get started in Visual Studio (2010) extensions and I am having a hard time finding the right materials. I have the SDK, but the included samples seem to be things like adorners, windows, and icons.
I am trying to make an extension that will work directly with the text editor (to alphabetize all of my method names in a class, or make all constant names upper case for example) but I can't find a demo for this type of functionality, or even a tutorial.
Does anyone know where I can find this kind of stuff?
I had the exact same question and now have browsed the web several hours until I was being able to understand and explain how you'd need to start with such an extension.
In my following example we will create a small and dumb extension which will always add "Hello" to the beginning of a code file when an edit has been made. It's very basic but should give you an idea how to continue developing this thing.
Be warned: You have to parse the code files completely on your own - Visual Studio does not give you any information about where classes, methods or whatever are and what they contain. That's the biggest hurdle to be taken when doing a code formatting tool and will not be covered in this answer.[*]
For those who skipped to this answer, make sure you downloaded and installed the Visual Studio SDK first or you will not find the project type mentioned in step one.
Creating the project
Start by creating a new project of the type "Visual C# > Extensibility > VSIX Project" (only visible if you selected .NET Framework 4 as the target framework). Please note that you may have to select the "Editor Classifier" project type instead of the "VSIX Project" type to get it working, s. comment below.
After the project has been created, the "source.extension.vsixmanifest" file will be opened, giving you the ability to set up product name, author, version, description, icon and so on. I think this step is pretty self-explaining, you can close the tab now and restore it later by opening the vsixmanifest file.
Creating a listener class to get notified about text editor instance creations
Next, we need to listen whenever a text editor has been created in Visual Studio and bind our code formatting tool to it. A text editor in VS2010 is an instance of IWpfTextView.
Add a new class to our project and name it TextViewCreationListener. This class has to implement the Microsoft.VisualStudio.Text.Editor.IWpfTextViewCreationListener interface. You need to add a reference to Microsoft.VisualStudio.Text.UI.Wpf to your project. The assembly DLL is found in your Visual Studio SDK directory under VisualStudioIntegration\Common\Assemblies\v4.0.
You have to implement the TextViewCreated method of the interface. This method has a parameter specifying the instance of the text editor which has been created. We will create a new code formatting class which this instance is passed to later on.
We need to make the TextViewCreationListener class visible to Visual Studio by specifying the attribute [Export(typeof(IWpfTextViewCreationListener))]. Add a reference to System.ComponentModel.Composition to your project for the Export attribute.
Additionally, we need to specify with which types of files the code formatter should be bound to the text editor. We only like to format code files and not plain text files, so we add the attribute [ContentType("code")] to the listener class. You have to add a reference to Microsoft.VisualStudio.CoreUtility to your project for this.
Also, we only want to change editable code and not the colors or adornments around it (as seen in the example projects), so we add the attribute [TextViewRole(PredefinedTextViewRoles.Editable)] to the class. Again you need a new reference, this time to Microsoft.VisualStudio.Text.UI.
Mark the class as internal sealed. At least that's my recommendation. Now your class should look similar to this:
[ContentType("code")]
[Export(typeof(IWpfTextViewCreationListener))]
[TextViewRole(PredefinedTextViewRoles.Editable)]
internal sealed class TextViewCreationListener : IWpfTextViewCreationListener
{
public void TextViewCreated(IWpfTextView textView)
{
}
}
Creating a class for code formatting
Next, we need a class handling the code formatting logic, sorting methods and so on. Again, in this example it will simply add "Hello" to the start of the file whenever an edit has been made.
Add a new class called Formatter to your project.
Add a constructor which takes one IWpfTextView argument. Remember that we wanted to pass the created editor instance to this formatting class in the TextViewCreated method of our listener class (simply add new Formatter(textView); to the method there).
Save the passed instance in a member variable. It'll become handy when formatting the code later on (e.g. for retrieving the caret position). Also tie up the Changed and PostChanged events of the TextBuffer property of the editor instance:
public Formatter(IWpfTextView view)
{
_view = view;
_view.TextBuffer.Changed += new EventHandler<TextContentChangedEventArgs>(TextBuffer_Changed);
_view.TextBuffer.PostChanged += new EventHandler(TextBuffer_PostChanged);
}
The Changed event is called every time an edit has been made (e.g. typing a char, pasting code or programmatical changes). Because it also reacts on programmatical changes I use a bool determining if our extension or the user / anything else is changing the code at the moment and call my custom FormatCode() method only if our extension is not already editing. Otherwise you'll recursively call this method which would crash Visual Studio:
private void TextBuffer_Changed(object sender, TextContentChangedEventArgs e)
{
if (!_isChangingText)
{
_isChangingText = true;
FormatCode(e);
}
}
We have to reset this bool member variable in the PostChanged event handler again to false.
Let's pass the event args of the Changed event to our custom FormatCode method because they contain what has changed between the last edit and now. Those edits are stored in the array e.Changes of the type INormalizedTextChangeCollection (s. the link at the end of my post for more information about this type). We loop through all those edits and call our custom HandleChange method with the new text which this edit has produced.
private void FormatCode(TextContentChangedEventArgs e)
{
if (e.Changes != null)
{
for (int i = 0; i < e.Changes.Count; i++)
{
HandleChange(e.Changes[0].NewText);
}
}
}
In the HandleChange method we could actually scan for keywords to handle those in a specific way (remember, you have to parse any code on yourself!) - but here we just dumbly add "Hello" to the start of the file for testing purposes. E.g. we have to change the TextBuffer of our editor instance. To do so, we need to create an ITextEdit object with which we can manipulate text and apply it's changes afterwards. The code is pretty self-explaining:
private void HandleChange(string newText)
{
ITextEdit edit = _view.TextBuffer.CreateEdit();
edit.Insert(0, "Hello");
edit.Apply();
}
When compiling this add-in, an experimental hive of Visual Studio starts up with only our extension loaded. Create a new C# file and start typing to see the results.
I hope this gives you some ideas how to continue in this topic. I have to explore it myself now.
I highly recommend the documentation of the text model of the editor on MSDN to get hints about how you could do this and that.
http://msdn.microsoft.com/en-us/library/dd885240.aspx#textmodel
Footnotes
[*] Note that Visual Studio 2015 or newer come with the Rosyln Compiler Platform, which indeed already analyzes C# and VB.NET files for you (and probably other pre-installed languages too) and exposes their hierarchical syntactical structure, but I'm not an expert in this topic yet to give an answer on how to use these new services. The basic progress of starting an editor extension stays the same as described in this answer anyway. Be aware that - if you use these services - you will become dependent on Visual Studio 2015+, and the extension will not work in earlier versions.
just have a look at the "Getting started with Editor extensions" site on the MSDN http://msdn.microsoft.com/en-us/library/dd885122.aspx
Thorsten

Categories