I have classes that are fluent and follow the builder pattern. For example a typical class might look like this:
public class ItemBuilder
{
private string _id = "SMITH-1001001";
//code for implementing the builder omitted for brevity
public ItemBuilder WithId(string id)
{
this._id = id;
return this;
}
}
Now it is not uncommon to be implementing a builder object for some poco that has multiple private fields (the one I'm staring at has 66) and I need to have a method as seen above for modifying each one if altering from the default.
I know how to create a snippet to generate a single method and tab through changing values as appropriate. I can also highlight a chunk of code and chose the snippet to wrap with try block.
So what I am wondering is if there is a way to mass generate the methods since they are 100% predictable.
For example I could highlight all 66 fields and choose my snippet which would generate 66 methods.
TIA
So the answer is....you can't do this via snippets. However the objective can still be met. What I ended up doing was writing a regular expression that parsed out the values then inserted them into a string. So I would copy all the private fields I wanted to use from vs to notepad ++. I then did a ctrl-h and put the regex in the find and the replacement string in the replace. From there it generated my methods and I cut and paste back to vs. Not 100% smooth but far better than manually typing them all.
Related
Why is the code below using a string_1 instead of straight using FileName?
And when would compiler generate code? What kind of source code or configuration of compiler (or anything else) would cause the [compiler generated] attribute?
[CompilerGenerated]
private string string_1;
public string FileName
{
[CompilerGenerated]
get
{
return string_1;
}
[CompilerGenerated]
private set
{
string_1 = value;
}
}
When you decompile auto properties of C# classes, you simply see this kind of pattern. The actual name string_1 is chosen by the decompilation engine, and different engines choose different ways to pick up such names.
You can read this article to learn more about decompilation of different C# syntax elements.
Update:
As the comments under this answer illustrated, there are several important spots in this code snippet that reveal more information than themselves,
The name string_1 is a common indicator of decompilation result from an obfuscated assembly through de-obfuscation process. Obfuscation removes the original *__BackingField names, and de-obfuscation adds back such type name_index names.
The missing DebuggerBrowsableAttribute attribute is usually the result of obfuscation (as de-obfuscation usually don't add such back).
Luckily the obfuscation process didn't remove the whole auto property pattern, so you can still tell what it might look like originally.
Note that most obfuscation tools can remove properties and leave behind only fields and methods.
public abstract class Unit
{
public abstract List<Move> allowedMoves{get;}
}
public class Javelineer : Unit
{
public List<Move> allowedMoves =>
new List<Move> {Move.Impale, Move.JavelinThrow, Move.ShieldBlock};
}
public class Dragon : Unit
{
public List<Move> allowedMoves =>
new List<Move> {Move.BreatheFire, Move.Swipe, Move.Bite, Move.Devour, Move.TailBash};
}
The X:
Given the above code, if and how can I retrieve the allowed moves of a given unit without necessarily instantiating a new object?
I know I can retrieve the property with this code:
typeof(Javelineer).GetProperty("allowedMoves")
But if and how can I retrieve the definition of this property?
The Y:
The client (web browser) must send the game server the player's unit. This includes the unit's type and moves this unit is able to perform (4 out of all available; similarily to Pokemon).
While the validation (of course) is performed on the server, the browser still needs to get a list of available unit types and allowed moves.
In order not to duplicate code, I would like to avoid hard-coding this data in Javascript.
Having read some excellent SO questions & answers I think I can retrieve all available units with code similar to this:
Assembly.GetExecutingAssembly().GetTypes().Where(
type => type.BaseType == typeof(Unit)
).Select(type => type.Name).ToList()
I'd call this code on server startup, cache the result and send the cached result to every connecting client, because I have feeling this code is likely expensive to call.
But how can I retrieve the list of allowed moves?
You have a couple of options, but TL;DR: Construct the object instance and read the property.
In any case, here are some options, creative minds might be able to find a couple more even.
Construct the instance, read the property.
This is your best option code-wise because it will be easy to understand, maintain, bugfix.
Rewrite the code to allow for easy detection of the values using reflection
One way to do this would be to use attributes, tagging the property or object with the legal moves. However, to avoid having the bug that the attributes does one thing, the code another, you might have to change the code to use the attributes as well, which would be a performance hit.
Additionally, reading those attributes would likely construct many more objects than your original object.
Use mono.cecil or some other IL-inspection library to decode the code of the property getter and finding the construction of that list, extracting the values being added to the list. You would essentially either have to dumb down the code of that property to be on par with what you have right now (and never allow it to become more complex) or basically simulate execution of code.
This is like constructing a flotilla of space warships with enough firepower to demolish a local starsystem, just to kill an ant.
Bottom line, construct the object instance, read the property.
I'm proposing using AutoFixture and AutoFixture.xUnit at our company, and have gotten the mandate that for certain objects and fields they want random data that is formatted in an expected way. For example, they want PersonName to only populate with realistic names (instead of GUIDs) and PhoneNumber to only make strings that look like phone numbers. But they DON'T want to add data annotations to the actual objects enforcing this, they would just like the test data generated by AutoFixture to be pretty.
I've dealt a bit with ICustomize classes to implement greedy constructor behavior on a few classes. Is there a similar way to override the data generation for specific objects? To (for example) pull names from a list, or generate data to follow a certain regular expression? (keeping in mind that I can't actually add those regular expressions as attributes on the model)
Ok, solved my problem.
Object generation for a given class type can be accomplished via the Fixture.Register method. You can make a method that returns the type you want to override and that will be used instead of the default.
To get meaningful data I just used Faker.Net.
I got the solution Mark pointed out working, and really liked it for general POJOs, but in my case many of my objects had properties that could only be set via the constructor or aggregate setters (like ChangeContactInfo), so unfortunately I needed something a bit more targeted. Here is an example of my solution implementing a name and address generation override:
public class CustomObjectGeneration : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Register(GenerateAddress);
fixture.Register(GeneratePersonName);
}
private Address GenerateAddress()
{
return new Address(Faker.Address.StreetAddress(), Faker.Address.SecondaryAddress(), Faker.Address.City(),
Faker.Address.ZipCode(), Faker.Address.UsState(), Faker.Address.Country());
}
private PersonName GeneratePersonName()
{
return new PersonName(Faker.Name.Prefix(), Faker.Name.First(), Faker.Name.First(), Faker.Name.Last(), Faker.Name.Suffix());
}
}
I am working on an application that has been edited by various programmers over the past few years and I have stumbled across a problem with using String Literals to access MenuItems.
For Example: in many places there is code like
mainMenu.MenuItems[1].MenuItems[0].Visible=true;
or
mainMenu.MenuItems["View"].MenuItems["FullScreen"].Visible=true;
how do I change the Strings used to identify the MenuItem and catch all of the places that it is being used for access? The menus and menuitems are declared as public and are used throughout this large application
What is the right way prevent the use of these magic indexes from being used. I forsee things being broken everytime a new item is added or the name is changed.
P.S. I have started using an enumerated dictionary approach in which every menuItem is paired with a key. but this still does not force other developers to use my implementation nor is it the most elegant solution to question 2
Give each menu item a name in the WinForms designer (I assume), and then refer to it by that name.
Then just use this in your code:
menuExit.Visible = false;
If the menu items are added programmatically, do this:
class MyForm : Form
{
private MenuItem menuExit;
...
myMenu.Items.Add(menuExit = new MenuItem(...));
...
}
and then still access it by the menuExit name. The key to avoiding magic numbers and strings is to just keep a direct reference to whatever it is you want to refer to. As a bonus, you can now rename this vairable safely using F2.
Romkyns answer is the correct one for this scenarion however if you do need to use string literals in your code I would alwasy keep them in public static classes such as:
public static class Constants
{
public static class Menu
{
public static readonly string FirstMenuName = "Menu 1";
...
}
public static class OtherCateogry
{
...
}
}
You can then access them by Constants.Menu.FirstMenuName.
As for definitively preventing other devs from using literals throughout code - you might have to make recourse to the Rod of Correction (sturdy metal ruler) ;).
I'm looking for a way to accelerate a repeatable task when I write code. I have ReSharper and I'm thinking a customization could do what I need.
I have two objects of the same type. I want to copy all of the public properties of one object to the other object. I want the tool, ReSharper in this case, to do generate the code for me. I'll tell it the names of the first object and the second object. I want it to find all the public properties of the first object and copy the values to the second object.
Here's the type of code I'm looking to have generated with a tool like ReSharper:
foo.Name = moo.Name;
foo.Age = moo.Age;
foo.City = moo.City;
Automating this simple code that copies values from right to left would save a ton of time and I'm thinking that ReSharper can do it. However, I haven't seen anything pop-up in searches for it though.
I'm not looking for a CodeSmith code generation technique or T4 template because I only want it to generate these specific lines inside my class, not generate and entire class or a separate file.
Does anyone know a way to press a few keystrokes, enter the "foo" and "moo" object names above and have the tool generate these copy from right to left lines of code?
Update:
I've found some documentation on building extensions to ReSharper, and this can probably be achieved by that path, but it looks really involved.
http://www.jetbrains.net/confluence/display/ReSharper/PowerToys+Pack+3.0+User+Guide
This is beginning to look like a weekend challenge unless someone else has already written it.
It's really easy. ReSharper doesn't do it, but you can use a super duper REGEX!
In Visual Studio:
public string Email { get; set; }
public string CellPhone { get; set; }
public int NumChildren { get; set; }
public DateTime BirthDate { get; set; }
Select all your properties. Hit CTRL-D to copy down.
Now hit CTRL-H to replace. Make sure .* is selected for Regex matching.
Replace: public [\w?]* (\w*) .* (This Regex may need to be tweaked)
With: dest.$1 = source.$1;
Now you have some beautiful code you can put in a method of your choosing:
dest.Email = source.Email;
dest.CellPhone = source.CellPhone;
dest.NumChildren = source.NumChildren;
dest.BirthDate = source.BirthDate;
EDIT: New alternatives
You can use AutoMapper for dynamic runtime mapping.
Mapping Generator is really nice for static mapping. It can generate the code above and it works well with R#.
This is somewhat derivative from answer by #Jess (his regex didn't work for me on VS2013) but instead of using Visual Studio I am using regex101
Click link above and just paste your properties into Test string field and you will get them mapped.
Regex I used
public [A-Za-z\?]* ([A-Za-z0-9]*) .*
and replace
Dest.$1 = Source.$1
hope this saves you some time.
I don't believe Resharper can do this, but Open Source AutoMapper can. New to AutoMapper? Check out the Getting Started page.
I agree with #Ben Griswold.
In most situations, Automapper is the way to go.
But when you truly want to generate code that copies properties from one object to another, try this:
Create a brand new class and derive from the class from which you want to copy properties.
Right-click on this new derived class and click 'Refactor > Extract Interface'.
Check all properties that you wish to copy.
Choose 'Place beside' because this interface will be only temporary.
Click 'Next'.
Modify your derived class so that you are no longer inheriting from the base class and you are only implementing your new interface. Expect to see a red squiggle.
Place your cursor over the red squiggle and hit 'ALT-ENTER' to 'Implement Members'.
Click 'Finish'.
Delete that temporary interface and modify your class so that you are no longer implementing it.
Here's a simple class to clone an object. It's not exactly what you asked for but perhaps this will be useful for you:
//.Net 2.0
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
namespace YourNameSpace {
public static class ObjectCloner {
public static T Clone<T>(T obj) {
using (MemoryStream buffer = new MemoryStream()) {
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(buffer, obj);
buffer.Position = 0;
T temp = (T)formatter.Deserialize(buffer);
return temp;
}
}
}
}
Based on #Matas answer I created a more robust version using regex101 that ignores generics, attributes and comments and normalizes spaces.
Regex: *((\/+.*\n*.*)|(\[.*\]\n*.*))*public [A-Za-z\_\?\<\>]* ([A-Za-z0-9\_]*).*(\n| )*
Replace: $4 = person.$4,\n
This is the kind of thing for which Cog shines. Basically, Cog is code generation tool. Code is generated via Python.
Simply copying values from one side to the other is pretty ugly.
You might find it better to create a method to include in your classes that uses reflection to copy public properties. You could save this method in resharper to regenerate into other classes you need this functionality in.