I am trying to improve some code to take out initialisations and use of the Service Locator in my View Model, so that the container can create them within the constructor. But there are changes to base classes that have hundreds of descendants and this will take a long time to manually fix everyone.
Is there a way that Visual Studio or any other add-in can do this for you? On the descendant it will need to add it into the main constructor and pass it through to the base constructor also. There is only a single constructor on all.
e.g. I have just added the someNewInjectedClass parameter to the base class constructor below:
public class BaseClass
{
private ISomeNewInjectedClass _someNewInjectedClass;
public BaseClass(ISomeNewInjectedClass someNewInjectedClass)
{
_someNewInjectedClass = someNewInjectedClass;
}
}
And that needs to be added to my descendant which is currently this:
public class OneOfManyDecendants : BaseClass
{
public OneOfManyDecendants()
: base()
{
}
}
To become this:
public class OneOfManyDecendants : BaseClass
{
public OneOfManyDecendants(ISomeNewInjectedClass someNewInjectedClass)
: base(someNewInjectedClass)
{
}
}
If you have Resharper you can use "Change Signature" (Ctrl+R,S) refactoring. When doing it select "Resolve with call tree" option. In a next dialog pick "Create parameter..." option for each subclass.
Not quite an answer to my exact question but I am going to go a long the lines of #sinatr's suggestion with this related post: Use class as a single parameter for base parameters
This seems the best way for us going forward and can more easily change in the future.
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!
I have implemented code in following fashion.
public abstract class BaseDocumentStep<T> where T : class, new()
{
protected T _document;
[Given(#"I Add New '(.*)'")]
public void GivenIAddNew(string p0)
{
Console.WriteLine(p0);
}
}
[Binding]
public class CustomerSteps : BaseDocumentStep<Customer>
{
}
[Binding]
public class EmployeeSteps : BaseDocumentStep<Employee>
{
}
Feature Files :-
a) Customer Feature
Scenario: Add New Customer
Given I Add New 'Customer'
b) Employee Feature
Scenario: Add New Employee
Given I Add New 'Employee'
When I run these scenarios. I got following error :
-> binding error: Ambiguous step definitions found for step 'Given I Add New 'Customer'': BaseDocumentStep1.GivenIAddNew(String), BaseDocumentStep1.GivenIAddNew(String)
After Scenario
I am not able to figure out, why specflow consider this step as ambiguous ?
Thanks in Advance.
Adi.
Adi,
Are there any reasons you want to use the abstract class for your tests? I have been using specflow for a few years now, and I have always tried to keep them simple and linear. Can you try to replace your step definition file with this:
[Binding]
public class EmployeeSteps
{
[Given(#"I Add New '(.*)'")]
public void GivenIAddNew(string p0)
{
Console.WriteLine(p0);
}
}
this is working fine for me. This should work out fine unless you have other reasons not to keep your steps this simple.
The problem here is that in Specflow all steps are global, and so if you declare a step in a base class, that step is also declared in every derived class. So you get one instance of
[Given(#"I Add New '(.*)'")]
public void GivenIAddNew(string p0)
{
Console.WriteLine(p0);
}
in CustomerSteps and EmployeeSteps
Step binding methods should not be declared in base classes, the steps will always be able to be found due to the fact that they are global.
It's not exactly clear what you want to achieve with your generic design, but perhaps if you give a bit more information about that (probably another question is better) then we might be able to help you get to a solution that does not require inheritance with binding classes.
I've been searching for a while on this because I'm naturally forgetful and I thought it would be nice to build something (an abstract class, interface, etc.?) that would force me to implement certain bits of code in a class I was writing.
In particular, I would like to force a new class to always have a constructor that takes a single parameter typed as itself in order to make duplication of the object easier. I've seen articles/questions elsewhere that talk about this, but I'm not sure this particular question has been asked (at least that I can find) or I'm simply not understanding enough of the other articles/questions to realize it. My apologies in advance.
I'm not interested in having a constructor in an abstract class, interface, etc. actually do anything. I'm merely interested in defining the requirement for a constructor signature in a derived class.
My ideal class would look like this:
public class GoodClass
{
public GoodClass(GoodClass goodClass)
{
// copy components of goodClass to this instance
}
}
So, I first began researching interfaces and also started reading up on abstract classes. I was thinking something like the code below would work, but alas I get errors. Is what I'm trying to do even possible? Is there any other way I could accomplish my goal without putting a sticky note on my monitor? :)
abstract class SelfConstructor
{
abstract public SelfConstructor(SelfConstructor) { }
}
class NewClass : SelfConstructor
{
//Required by SelfConstructor:
public NewClass(NewClass newClass)
{
// copy components of newClass to this instance
}
}
You could write a ReSharper plugin that recognises this case and highlights the class if it doesn't have a "copy constructor". This would be a daemon stage that would process the file as it's being edited, and add highlights. You can look through the abstract syntax tree of the file, look for all instances of IConstructorDeclaration, and then get the constructor's parameters from the ParameterDeclarations property. You can check that there is a constructor that only has one parameter, and that parameter is the same type as the class it's declared in.
You can compare the types by getting the constructor's parameter's TypeUsage and trying to downcast to IUserTypeUsage. You can then use ScalarTypeName.Reference.Resolve() to get an instance of IDeclaredElement. Compare this against the class's IClassDeclaration.DeclaredElement to see if they're the same instance.
In C++, what you are talking about is a copy constructor, you actually get one by default!
C# doesn't have that concept (though of course you can define one); however, it is easier (and preferred) to simply implement ICloneable (MSDN), which requires you to implement the Clone method, that does the same thing.
Instead of:
object myObj = new CloneableObject(otherObj);
You write:
object myObj = otherObj.Clone();
The other thing you could do is force a constructor signature by not having a default:
public class BaseClass
{
//No abstract constructors!
public BaseClass(BaseClass copy)
{
}
}
Now when you derive, you have to use that overload in the constructor. Nothing will force the derived signature, but at least you have to explicitly use it:
public class DerivedClass : BaseClass
{
public DerivedClass() : base(this)
{
}
}
The above example clearly shows that it doesn't "force" you to have a copy constructor, but like a sticky note, would serve as a good reminder.
I would definitely go the interface route, as that is what is there for (and you can use an abstract implementation!).
Note that you can take advantage of Object.MemberwiseClone if you want a shallow copy for free. All objects get this, no interface required.
Here's my situation. In Java I can mark a method as final in the base/super class and there is no way a derived class can mask a method of the same signature. In C# however, the new keyword allows someone inheriting my class to create a method with the same signature.
See my example below. I need to keep the orignal.MyClass public so please don't suggest that as an answer. This seems to be a lost feature moving from Java to C#:
public class orignal.MyClass{
public void MyMethod()
{
// Do something
}
}
class fake.MyClass: orignal.MyClass {
// How to prevent the following
public new void MyMethod()
{
// Do something different
}
}
EDIT: Not a duplicate.
All answers seem to suggest, it's not possible to prevent a method from being hidden/shadowed in a derived class. This became apparent while migrating some old Java code to C#. A final method in Java will not let anybody use the same method signature in any derived class. While it's great in most scenarios that C# allows a method of same signature in the derived class, it would have been great to prevent such a behavior if warranted.
// How to prevent the following
There is no way to prevent this. It's allowed by the language.
Note that, in practice, this rarely matters. If you expect your base class to be used as your class, your method will still be called. Using new only hides the method when using the DerivedClass from a a variable declared as DerivedClass.
This means that your API, if built around MyClass, will always still call MyMethod when instances are passed into your methods.
Edit in response to comments:
If you are worried about people subclassing your class in general, the only real option you do have would be to seal your class:
public sealed class MyClass
{
This will prevent people from creating a subclass entirely. If you want to allow people to derive from your class, however, there is no way to prevent them from hiding your method in their class.
You can't prevent a public method or property being masked, but why would you? It takes a deliberate action from whoever extends the base class to do this (i.e. they need to type new), so they have intended to do it, why try and stop them?
Maybe you need to switch your pattern up a bit? If the extender must use your base method then you can put something critical in it, thus forcing them to call it. Of course this is smelly if not done correctly, so if you use this approach then mark your method as virtual, then in the documentation (or method header comments) mention that the base method must be called. This way you avoid the extender having to hide/mask your method (although they still could), but they can still extend it if they want.
I'm assuming you really want to prevent someone from overriding the method - hiding a method with new cannot be prevented, but it poses no risk to the base class, so that shouldn't be an issue.
In C# methods are not overrideable by default. So you can simply prevent someone form overriding a base method by not marking it virtual or abstract. In Java methods are virtual by default, so sealing a method by using final is necessary to prevent overriding.
I think the only way is to create interface the put your method definition within it, then let the original class to implement the interface and implement the method explicitly:
interface IAnimal
{
string diary(string notes, int sleephours);
}
class Dogs:IAnimal
{
virtual public string voice()
{
string v = "Hao Hao"; return v;
}
string IAnimal.diary(string notes,int sleephours)
{
return notes + sleep.ToString() + " hours";
}
}
class Cats:Dogs
{
public override string voice()
{
string v = "Miao Miao"; return v;
}
}
You will not use diary() method via Cats instance.
For prevent of hiding base class method you can do like this:
public class Org
{
public void Do()
{
// do something
}
}
public class Fake : Org
{
public new void Do()
{
base.Do();
// do something
}
}
here the base keyword refers to Father class.
now you called method from Father class (here is Org) in child class and now this method doesnt hide anymore.
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.