Can VS 2012 professional generate a class constructor without any addons?
I can't believe I can't find the option to do this, and if it can't do it, it truly is a conspiracy :)
I have my class defined:
public class User
{
public int Id {get;set;}
public string Name {get;set;}
}
Now is there a shortcut that will generate the constructor, toString() method etc?
If you need a default constructor then there is a code snippet ctor for it.
But if you need a constructor with parameters then in you code write:
User user = new User(2, "Name");
This will be an error, since there is no constructor with two parameters, but you will get a blue under line if you hover your mouse over User in new User. Click on that or put your cursor on User and press Ctrl + . It will give you an option to generate constructor like:
That will give you a constructor with fields like:
public class User
{
private int p1;
private string p2;
public User(int p1, string p2)
{
// TODO: Complete member initialization
this.p1 = p1;
this.p2 = p2;
}
public int Id { get; set; }
public string Name { get; set; }
}
Then you have to go in and remove p1, p2 and point to Id, Name and also rename parameters in constructor. That is probably the best you can do with only Visual studio.
See: Generate From Usage - MSDN (thanks to #Peter Ritchie)
Consider installing Re-Sharper it has much better option for generating not only constructor but other very helpful code.
snippets are built in and you can add your own. ctor will make the constructor, I don't think there is anything for ToString, though you can just type override, pick it from the list and it will stub it out.
"ctor" snippet generates a constructor, but without parameters. To get them, you should unfortunately use (free or not) addons. This question has been already discussed, see Shortcut for creating constructor with variables (C# VS2010) for example.
I think there is no direct mean to generate a paramerized constructor in a bare Visual Studio.
Edit : I should probably have added after my last sentence "... which strictly applies to properties and fields currently defined in class". But yes, following Peter's advice it is possible to generate a kind of parameterized constructor.
Related
There is a bit of C# syntax that I don't understand.
I am on the receiving end of a couple of classes. Simplified, let's say it's this
public class ParentClass
{
public ParentClass();
public RandomEnumerated Random_Enumerated; //No get/set. Relevant?
}
public class ReceivedClass : ParentClass
{
public ReceivedClass();
public char Random_Field { get; set; }
}
When I do this
public class ExtendedReceivedClass : ReceivedClass
{
public ExtendedReceivedClass();
public char A_New_Random_Field_of_My_Own { get; set; }
}
I get hit by the error
ExtendedReceivedClass.ExtendedReceivedClass() must declare a body because it is not marked abstract, extern, or partial FuelTaCSClient
So instead of being able to do what the parental classes do
public ParentClass();
or
public ReceivedClass();
I have to do this
public LocalWreckerVehicleClass() {}
So my question is
a
Is the "public ReceivedClass();" in ReceivedClass the constructor? Same for ParentClass.
b
If it is, why can they do a shortcut version but I can't
or
if it isn't, what is it?
"I am on the receiving end of a couple of classes" -- I think you're looking at those classes using Visual Studio's "Go To Definition" or similar, and they're defined in another DLL?
You'll notice that Visual Studio is showing you method signatures, but not the bodies of the methods: when all it has is a DLL, it's easy to get the signatures, but harder to get the original C# code which was used to build the DLL. This is just intended to give you an overview of what methods are available, and it's not supposed to be valid C#.
public ParentClass(); is not valid C#. It's the signature of a constructor (showing that there's a public parameterless constructor), but when you define a constructor in C# you need to provide a body:
public ParentClass()
{
// ...
}
I am going to accept this as the answer because it seems to make the most sense. I have no trouble believing that when I ask VS to tell me what is in a parent class that it will give me an abbreviated and slightly askew version of what's actually in it.
I am doing a hard search for the parent class by name using a third-party search tool and if I see anything that either affirms or refutes this conclusion I will post an update.
Thank you to everyone who helped! And canton7 - thank you and have this upvote!
Is it possible to tell what file instantiated a class in C#?
For example, If I had Page1.cs and Page2.cs could a constructor in myclass.cs know what page created an object from it?
You can do this via the "Caller Information" attributes. Essentially you create some extra optional parameters on your class' constructor, apply some special attributes to them, and the compiler will fill in the details for you automatically. For example:
using System.Runtime.CompilerServices;
public MyClass
{
public MyClass(
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
...
}
}
You just need to call it as:
var instance = new MyClass();
and the compiler will fill in the caller's member name, file path and line number automatically.
A class can learn what class instantiated it by inspecting the stack trace during construction. So for example if you were to add this to your class' constructor:
var creator = new StackTrace().GetFrame(1).GetMethod().DeclaringType.FullName;
...you'd learn the location of the code that called new. Location as in the name of the class. You can of course inspect the declaring type's properties to learn the assembly name, location, etc.
Just bear in mind that you'd have to walk the stack frame a bit further if you have chained constructors. Also, this won't work for any object that was created through deserialization.
SOLUTION 1 (requires .NET 4.5 and editing your code)
Suppose that this is Caller.cs
public class Caller
{
public Caller()
{
new Callee();
}
}
and this is Callee (the class that will be called):
using System.Runtime.CompilerServices;
...
public class Callee
{
public Callee([CallerFilePath] string callerFileName = "")
{
Console.WriteLine(callerFileName);
}
}
The output will be
c:\users\francesco\source\repos\ConsoleApp19\ConsoleApp19\Caller.cs
A longer explanation is e.g. here; [CallerFilePath] will take care of retrieving the caller file name and store it in the callerFileName parameter of the constructor of Callee.
This requires editing your source code and at least .NET 4.5, which I'm not sure is a requirement every application will satisfy.
SOLUTION 2 (requires just editing your code)
So, you can just change the constructor of Callee to pass it a string parameter, which will be the name of your Caller (e.g. "Caller.cs"):
public class Caller
{
public Caller()
{
new Callee("Caller.cs");
}
}
public class Callee
{
public Callee(string callerFileName = "")
{
Console.WriteLine(callerFileName );
}
}
Which of course will be a viable solution if you just have a few classes (Caller being one of them) and will work with every version of the .NET framework.
Anyway it's not recommended to use a file to host several classes, but it might have been done by someone else in legacy code: so you can get the file name but still not the calling class, which is why you can use the method I just listed (directly passing the name of the caller to the constructor) instead of the first.
SOLUTION 3 (requires no code edits)
Last but not least, if you are just debugging from Visual Studio, you don't have to do any of the above: just use StackFrame: set a breakpoint to the constructor of Callee and click on the StackFrame dropdown:
This will require no code editing whatsoever, and clearly shows that the constructor of Callee is called by Caller; you can just click on any line of the menu and you will be brought to the calling line.
I have a question if Resharper can help me with below problem.
Let's say there is a class with many properties inside:
public class TestClass {
public string variableA {get; set;}
public string variableB {get; set;}
public int variableC {get; set;}
}
then somewhere else we have a method that uses TestClass object
public void TestMethod(TestClass classInstance) {
classInstance.variableA = 'new value';
classInstance.variableC = 1;
}
of course this example is much simplified to the one I have, but I want somehow to extract interface that will have only
variableA
variableC
because then I want to pass it as a parameter to TestMethod. Can ReSharper do it automatically?
Right click the class
Select Refactor -> Extract -> Extract interface.
It takes you to extract interface window, in which you can select all the properties you want to extract it to a new interface.
In visual studio keyboard scheme shortcut happens to be ctrl + shift + R, x or select "Extract interface".
Once this refactoring is done, it is simply the matter of changing the method's formal parameter to use your interface as opposed to the concrete type.
I did what I wanted and I want to share solution, or maybe better say small workaround.
first what I did was to create an interface that contained all properties from the TestClass.
I changed method signature to get this interface instead of class itself.
I turned on wide analysis in R# and checked which properties are not used and removed them from the interface.
Maybe someone will need this in future when refactoring. Anyway - thanks for your help!
I know properties have some advantages, but if you think you won't need a property, what's the harm in making it a public instance?
People say that changing the public field to a property will break code if you try to do it later on but in my experience changing it to a property breaks nothing.
I think that people mean that it breaks ABI (binary) compatibility, not the API (source) compatibility.
Although the syntax is identical, behind the scenes, access to properties and access to member variables are compiled differently.
That said, if your variable/property is not to be used from an assembly that you yourself do not compile, then there is no harm in changing it. But if it is part of a public interface, then it is better to make it a property, so that you will not regret it in the future.
It's about maintaining both binary and source compatibility. Some time in the future you may decide to make logic of assigning values more complex and to change fields to properties. This is where the problems emerge.
Public fields can be used as out and ref parameters. Properties cannot. This will produce uncompilable code.
Different Reflection methods are used to access fields and properties. That means any code that gets or sets values using Reflection will break, and you'll know about it only in run time.
Different IL operators are used to access fields and properties. That means cross-assembly compatibility is broken when fields are changed to properties and only one assembly is recompiled. This will make your program fail at run time.
I concour with you, if the property is just a wrapper on the field.
And the guys at Coding Horror looks like having our same opinion, I find very funny that frightened icon they use :)
http://www.codinghorror.com/blog/2006/08/properties-vs-public-variables.html
A simple program.
Here I am adding two properties and one variables. We can use properties as per our decision. But I prefer to use properties because it helps to implement some bussiness validation and can hide the business logic form calling party.
class Program
{
static void Main(string[] args)
{
Human h = new Human();
h.FirstName = "Test";
h.LastName = "User";
Console.WriteLine(h.FullName);
Console.Read();
}
}
class Human
{
public string FullName { get { return FirstName + " " + LastName; } }
public string FirstName;//{ get; set; }
public string LastName;//{ get; set; }
}
I'm using ManyConsole as a command line command and options parser for a console app. All commands are defined as a command class that derives from ConsoleCommand, and then implement a specific task. I defined an intermediary base class, ParkPayConsoleCommand derived from that class:
abstract class ParkPayConsoleCommand: ConsoleCommand
{
protected readonly ParkPayDbContext DbContext = new ParkPayDbContext();
}
Then all my command classes derive from my base class, and enjoy a built in DbContext, e.g:
class ReadStartsCommand : ParkPayConsoleCommand
{
public ReadStartsCommand()
{
_commandTrace = new TraceSource(CommandName, SourceLevels.All);
IsCommand("read-starts", "Processes imported vehicle entry movements to create new VehiclePresence records with start date-times based on those movements");
HasRequiredOption("b|batchId:", "The Id of the VehicleMovementBatch used to create new vehicle presences.", b => _batchIdOption = b);
}
public override int Run(string[] remainingArguments)
{
// Do the business of the command.
return (int)ExitCodes.Success;
}
}
It's a ManyConsole convention for each command class to name and describe itself, and define its command line options in its constructor, as you see above. Normally when I run a command such as the ReadStartsCommand above, it just writes to console what command is running, and not what options I passed.
Yet when I make ParkPayConsoleCommand.DbContext public, not protected, it outputs the string
DbContext : ParkPay.Model.Context.ParkPayDbContext
to the console at the end of the running command's name and description. Why does it do this when DbContext is not anywhere defined as a command option itself. This may seem trivial, but essentially I'm asking quite an important 'meta-question', and that is: Does ManyConsole implicitly interpret all public properties of its command classes as command options, even if they are not explicitly declared as such?
I can't speak to the original intent, but as you've found out, yes, it appears to do that. A suggestion of why this might be useful:
Sometimes the commandline options do not map 1-to-1 on to Properties of your ConsoleCommand class. Consider
public class VerbosityCommand : ConsoleCommand
{
public int VerbosityLevel {get;set;}
public VerbosityCommand(){
this.IsCommand("Verbosity","Control the level of verbosity");
this.HasOption("v|verbose","Increase verbosity, cumulative",x => Verbosity++);
}
}
Now the block printed by ManyConsole will (helpfully) have VerbosityLevel : 3 (for example) rather than (unhelpfully) have
Verbose : set
Verbose : set
Verbose : set
or something similar.
Another example would be preset-type flags, which configure a number of properties in to common configurations.
In your case, it might be useful to make _batchIdOption public and ParkPayDbContext protected or private.
Basically yes all public properties are printed as Greg said. This does not imply they are all treated as arguments (and they are not). Some additional points:
if you do any work overriding OverrideAfterHandlingArgumentsBeforeRun() and assign the result to public members, that result will show up when the command is printed to the console. This can be useful to document some intermediate result for the user
to format how the members are printed, you can override ToString on the public member's type
I hope using ManyConsole is smooth otherwise.