I have a virtual method on a base class. Each time I override it, I want to return different object types. I know this is not possible, but what would be the best way to handle this situation?
Example of base method:
public virtual void clickContinue()
{
//click the continue button
}
And the method that overrides it:
public override myObject clickContinue()
{
//click then continue button
//return myObject
}
I need to do several similar overrides, all returning different objects. Again, I know this can't be done the way it's done above - I trying to figure out the best way to handle this situation.
I know this is not possible, but what would be the best way to handle this situation?
If you don't need a default implementation, you can potentially make the class generic, and return the generic type:
abstract class YourBase<T>
{
abstract T ClickContinue();
}
class YourOverride : YourBase<MyObject>
{
override MyObject ClickContinue()
{
//...
I sense an abuse of the override mechanic. The idea behind it is that you do the same thing but with different parameters. The name of the method actually should tell you what it does. So how is it possible the the very same procedure returns void (doesn't return anything) and on occasion returns something (non-void)?
Are you sure you should not have two completely different methods? This would probably make the API clearer, too.
Otherwise, consider returning always object, which happens to always be null in case (instead) of the void override.
Obviously, the generic way is better for type-safety. Returning object means you abandon typing and take over casting manually.
Related
Does anyone have a better way to do the following:
typeof(Service).GetMethod("UpdateData")
.MakeGenericMethod(dataType)
.Invoke(_myService, new object[]{ editData, metaData });
I'd love to do something like:
_myService.UpdateData<dataType>(editData, metaData);
But the <> accessor for generics will not take Type objects. I'm looking for a helper, utility, accessor, or something to make those generic method calls with reflection less cumbersome or at least centralized.
More Specific Example
public class UserService : IUserService
{
async Task<User> UpdateUser<T>(User user, JsonPatchDocument<T> patch){ //do code }
}
Type dtoType = MagicService.getDynamicDtoType();
Type patchType = typeof(JsonPatchDocument<>).MakeGenericType(dtoType);
dynamic patchDoc = _mapper.Map(patch, typeof(JsonPatchDocument<User>), patchType);
User updateUser = await (Task<User>)typeof(UserService).GetMethod("UpdateUser").MakeGenericMethod(dtoType).Invoke(_userService, new object[]{user, patchDoc})
This actually ends up with two issues. One, the dynamic patchDoc isn't the right type to be used in UpdateUser, which I have a separate question in Stackoverflow about (but you can use duck typing here), and the messy calling of that generic method call with reflection. I'm trying to solve both, but for this question I want to clean up the call. If you have ideas on the other piece, which is really a separate issue:
Declaring a type in C# with a Type instance
This answer does not use reflection, but may make your code easier to work with in some circumstances.
We could have a class like this:
public class MyService
{
public void UpdateData<T>(Something data, Something otherData)
{
// do stuff
}
}
Later we find that we have to call it using a Type variable instead of a generic argument, which could mean using reflection. Sometimes it's easier to add a non-generic overload to the original class, and call it from the generic method:
public class MyService
{
public void UpdateData(Type dataType, Something data, Something otherData)
{
// do stuff
}
public void UpdateData<T>(Something data, Something otherData)
{
UpdateData(typeof(T), data, otherData);
}
}
We lose the ability to easily impose constraints on the Type argument like we could with the generic method. We can add validation if we need it.
That gets you as close as possible to the code you're trying to write:
_myService.UpdateData(dataType, editData, metaData);
That's assuming that you find yourself still needing the generic methods at all. If you add non-generic overloads and discover that you're not calling the generic ones anymore, you can just delete them.
A significant benefit of this over reflection is that you can identify where your code is called. A method that's only called using reflection will appear unused.
Sorry if the question sounds confusing. What I mean is that if I have a class that has a method that does a bunch of calculations and then returns a value, I can either make that method public (which gives my other classes access), or I can make it private and make a public get method.
Something like this:
public publicmethod{
return privatemethod();
}
private privatemethod{
//do stuff
return value;
}
Is this a futile exercise or does it provide additional program security?
Well, there is no additional security here. However, such a usage can sometimes make sense.
For example, the private and public method may have different semantics.
// base class
public virtual BuyFood()
{
BuyPizza();
BuyCoke();
}
private void BuyPizza()
{
// ...
}
// derived class
public override void BuyFood()
{
BuyChopSuey();
}
private void BuyChopSuey()
{
// ...
}
So your implementation is just calling to a private method -- but what is important, you expose the semantics: your BuyFood operation is just BuyChopSuey(). Your code says: "in this class, buying food is just buying chop suey" in a clear way. You are able to add BuyTsingtaoBeer() into BuyFood() any time without changing the semantics of the both methods.
It is completely redundant. It does not provide anything except another name for the same thing and another indirection for readers to follow. Simply make a single implementation, and make it public. On the same note, getX() { return x; } setX(T newX) { x = newX; } does not encapsulate anything, at best it's future-proofing.
You may end up implementing a particular function required by an interface in a single line, largely delegating to (possibly private) methods which exist for other good reasons. This is different, and more justified (but again, if it's only return someMethod(); you should probably abolish the private implementation and assume the common name). A particular case if when you need two implement two methods which do the same thing (e.g. from separate interfaces).
I think either way is fine, it's more a matter of style assuming the method doesn't change the state of the class. If you have a class that has a bunch of properties and very few methods, it probably makes more sense to define another property. If you have a lot of methods in the class but few properties, then a method is more consistent with your overall class design.
If the method changes a bunch of other class variables than I'd expose it as a public method instead of a property.
I don't think either way, property or method, is necessarily more secure. It depends on what checks you do - is the caller allowed to perform the calculation? Are all variables used in the calculations within acceptable ranges? Etc. All of these checks can be performed whether you are using a property or a method.
Well, actually the question is What code do I want to be able to call this method?
Any code in general, even from other assemblies? Make the method public.
Any code from the same assembly? Make it internal.
Only code from this class? Make it private.
Having a private method directly aliased to a public method only makes the private method callable from the outside, which contradicts its private status.
If the method only does some calculation and doesn't use or change anything in the object, make it a public static method:
public static CalculationMethod(int input) {
//do stuff
return value;
}
That way any code can use the method without having the create an instance of the class:
int result = ClassName.CalculationMethod(42);
Instead of public consider internal, which would give access only to code in the same assembly.
When you override a method, you shouldn't change the behaviour of the method, you just specialise it. Therefore you have to call base.MyVirtualMethod() in the overridden method and add the specialisation code.
But I'm always wondering when I have to call the base.MyVirtualMethod(). Or from another point of view, how do I write my virtual method? Should I expect the user will call it as the first or the last thing the overridden method does?
public class Parent
{
public virtual void MyMethod(){ /* Some code*/ }
}
public class Child : Parent
{
public override void MyMethod()
{
/* Does my code goes here? */
base.MyMethod();
/* Or does my code goes here? */
}
}
Therefore you have to call base.MyVirtualMethod() in the overridden
method and add the specialisation code.
That is not always true - there are cases when you don't want to do in the derived class what the superclass is doing so you don't want to call base.
If you want to extent the base behavior you place your code before or after base call, depending on the actual problem. There is no rule 'always call base before your code'.
The base call does not have to be present. You can specify in the documentation whether the base call should be before other code, after other code, both, or neither (absent), and exactly what the nature of the other code should be. This will all depend on what you are trying to accomplish.
If you find that the best place for the additional code would really be somewhere inside the base call, then that means the base method should be split into two or more methods.
The answer is, as with many questions, "It depends".
Assume that you're extending class which writes some data to a file, and the extension needs to add more data at the end of the file (SimpleDataFile.writeFile() extended by ExtendedDataFile.writeFile()): in such a scenario, you would add your code after the call to the base method.
Now, assume your extension adds a pre-processing facility, maybe adding color to the base file output (SimpleDataFile.writeFile() extended by FancyDataFile.writeFile()): in such a scenario you would realistically act before anything is sent to the file, and your code would end up before the base call.
To answer your question accurately: don't override it :) When you override it, you will change the behaviour.
Most of the times I put new code below the calling of the base method, since it does perform this base behaviour and then some more additional behaviour. However this is not set in stone, and really depends on your needs.
I generally call the base method first to assure that any required initialization has already happened and that my code actually overrides the base behavior, instead of the other way around.
Obviously this depends on the specific situation though, there may very well be occasions where you know your code needs to run first.
It depends on what you wanna do but both are OK !
Apologies if these are extremely basic questions, but let's say I'm using the void Add(T item) function of BlockingCollection:
1) How would I override the Add function, i.e. if I want to add a check at the beginning and then call the base function, is this possible to do, and if so, would the code look something like this?
protected sealed class BlockingCollection<T> : IEnumerable<T>
{
protected override void Add(T item)
{
// do something here
// call base blockingcollection add function, something like return base.Add(item)??
}
}
2) If instead of calling the base function, I wanted to actually modify the Add code, is there a way to get the underlying code for the Add function? Would I use something such as Reflection? If so, is there any way to get the underlying code without writing my own program and using reflection to get the method code (i.e. can I get the underlying method code within the Visual Studio IDE itself without having to write / compile / run code every time I want to get the underlying code of a method?)?
IEnumerable doesn't have an "Add" method; you'd have to implement your own. ICollection does, however!
Also, because IEnumerable/ICollection are interfaces, not classes, there's no existing implmementation for you to override. You have to do that part yourself.
Edit for possible additional extra super duper correctness:
If you're trying to subclass BlockingCollection and you want to do some additional "stuff" before T is added via "Add", you could do it like this:
public class Foo<T> : BlockingCollection<T>
{
public new void Add(T item)
{
base.Add(item);
base.Add(item);
}
}
So, this extremely simple implementation will add anything you put into your Foo via "Add" twice.
I hope you are aware that you are creating a brand new BlockingCollection class, you aren't modifying the System.Collections.Concurrent.BlockingCollection<T> class that's part of the BCL.
Actually modifying the library version of BlockingCollection<T>.Add would be quite difficult to say the least. It's distributed as a signed binary, and .NET doesn't provide a detours-style mechanism. Although DynamicMethod allows you to add new methods to existing classes, I don't think you can use it to replace existing methods.
1) Yes, that is the correct way to do what you are asking.
2) You use a decompiler to view source code for a library API you are choosing to override. This is done by you, the human, and not as part of program execution.
Reflection is a bit different. It allows your code to access an API at run time, but does not access nor expose the API's source code. There are a lot of resources out there, but you could start on MSDN.
Update:
Since the method you are overriding is void, you may not change the implementation by returning something. Try this:
protected override void Add(T item)
{
// do something here
// call base blockingcollection add function
base.Add(item);
// this is unnecessary, but you could do it for giggles
return;
}
If the original library has allowed you to override Add then the pseudo-code you show is along the right track. You do need a bit of modification though if I understand your question properly.
First, you would create your own class, inheriting the old class and if not already done by the old class implementing the IEnumerable interface. Of course if the old class is "sealed" you will not be able to do this.
protected sealed class MyBlockingCollection<T> : BlockingCollection<T>, IEnumerable<T>
{
protected override void Add<T>(T item)
{
}
}
now marking your class as sealed will prevent anyone from further overriding methods exposed. If the old class is marked sealed, you will not be able to do this.
To see the code, you will need to decompile the library, using a tool which could be easy or difficult depending on the level of obfuscation that may or may not be employed to keep you from doing just that.
Edit: just winging the code, you should check a reference to ensure you have the appropriate syntax for what you are trying to do.
I have the following snippet of code that's generating the "Use new keyword if hiding was intended" warning in VS2008:
public double Foo(double param)
{
return base.Foo(param);
}
The Foo() function in the base class is protected and I want to expose it to a unit test by putting it in wrapper class solely for the purpose of unit testing. I.e. the wrapper class will not be used for anything else. So one question I have is: is this accepted practice?
Back to the new warning. Why would I have to new the overriding function in this scenario?
The new just makes it absolutely clear that you know you are stomping over an existing method. Since the existing code was protected, it isn't as big a deal - you can safely add the new to stop it moaning.
The difference comes when your method does something different; any variable that references the derived class and calls Foo() would do something different (even with the same object) as one that references the base class and calls Foo():
SomeDerived obj = new SomeDerived();
obj.Foo(); // runs the new code
SomeBase objBase = obj; // still the same object
objBase.Foo(); // runs the old code
This could obviously have an impact on any existing code that knows about SomeDerived and calls Foo() - i.e. it is now running a completely different method.
Also, note that you could mark it protected internal, and use [InternalsVisibleTo] to provide access to your unit test (this is the most common use of [InternalsVisibleTo]; then your unit-tests can access it directly without the derived class.
The key is that you're not overriding the method. You're hiding it. If you were overriding it, you'd need the override keyword (at which point, unless it's virtual, the compiler would complain because you can't override a non-virtual method).
You use the new keyword to tell both the compiler and anyone reading the code, "It's okay, I know this is only hiding the base method and not overriding it - that's what I meant to do."
Frankly I think it's rarely a good idea to hide methods - I'd use a different method name, like Craig suggested - but that's a different discussion.
You're changing the visibility without the name. Call your function TestFoo and it will work. Yes, IMHO it's acceptable to subclass for this reason.
You'll always find some tricky situations where the new keyword can be used for hiding while it can be avoided most of the times.
However, recently I really needed this keyword, mainly because the language lacks some other proper synthax features to complete an existing accessor for instance:
If you consider an old-fashioned class like:
KeyedCollection<TKey, TItem>
You will notice that the accesor for acessing the items trough index is:
TItem this[Int32 index] { get; set; }
Has both { get; set; } and they are of course mandatory due to the inheritance regarding ICollection<T> and Collection<T>, but there is only one { get; } for acessing the items through their keys (I have some guesses about this design and there is plenty of reasons for that, so please note that I picked up the KeyedCollection<TKey, TItem>) just for illustrations purposes).
Anyway so there is only one getter for the keys access:
TItem this[TKey key] { get; }
But what about if I want to add the { set; } support, technically speaking it's not that stupid especially if you keep reasoning from the former definition of the propery, it's just a method... the only way is to implement explicitly another dummy interface but when you want to make implicit you have to come up with the new keyword, I'm hiding the accessor definition, keeping the get; base definition and just add a set stuffed with some personal things to make it work.
I think for this very specific scenario, this keyword is perfecly applicable, in particular in regards to a context where there is no brought to the { get; } part.
public new TItem this[TKey key]
{
get { return base... }
set { ... }
}
That's pretty much the only trick to avoid this sort of warning cause the compiler is suggesting you that you're maybe hiding without realizing what you are doing.