I'm writing a set of unit tests for a large, complex class called ImageEditor from a piece of legacy code, where image processing and GUI functionality isn't strictly divided. One of the methods in the class, BaseImageChanged, seems to be concerned entirely with how images get displayed and should be disabled in my unit tests to avoid unnecessary complexity. The test project is in C#, and the original code is in VB; my idea was to create a Decorator for the class in C# and then hide the method behind an empty one that does nothing. However, when I try running the unit test, the VB code keeps referencing the old BaseImageChanged method as though the replacement didn't exist. Here's what I'm doing:
(VB class)
Public Class ImageEditor
...
Public Sub BaseImageChanged()
...
End Sub
...
End Class
(C# class)
class ImageEditorTestingClass : ImageEditor_Accessor
{
public new void BaseImageChanged() {}
}
Is there a way to accomplish this sort of interoperability, or will I have to find another way?
EDIT: The compiler error turned out to be a problem with reflection. Also, overriding the method didn't work as long as the base class was an accessor of ImageEditor instead of the original ImageEditor class.(No compiler error, but the base method's behavior wasn't overridden.)
Do you have access to the VB code? if so mark it virtual (C# syntax); Then in the C# code override it with an empty body so that id does nothing.
You should (almost) never use 'new' to redeclare methods or properties. If some code is assuming it's the base class, even if you pass a derived one, the base methods will be called.
For better understanding read about late-binding and early-binding in .NET
Early and late binding
It seems #estanford accepted this answer due to my comment below
"Where you call BaseImageChanged try using reflection"
I don't know VB at all, but this sounds more like a case for a virtual method with an override than a method hiding. The VB code is probably calling "this.BaseImageChanged()" somewhere, which wouldn't call your new method... right?
It looks like what's going on here is that
You have a library written in VB.Net
Your unit tests are written in C# and are using MSTest
You're trying to derive from the generated accessor instead of the original class
In this case the only option you have is to use new. The generated accessor class will not add virtual methods and hence if you want to provide an alternate method with the same name new is the only way to do so.
Related
I am working with Visual Studio Coded UI Tests, and wish to persist tweaks to the generated code.
The code is generated as a partial class in UIMap.cs and UIMap.Designer.cs, and so I know one solution would be to create a method with a slightly different name, such as myMethod_persist in UIMap.cs and use this instead of myMethod in UIMap.Designer.cs, which will be overwritten every time the source is regenerated.
This however seems very messy, and so what I'd prefer, is to instead override myMethod in UIMap.cs. This way the interface is not complicated with lots of gumph, and I don't have to remember to change every instance of myMethod in calling code to myMethod_persist
Unfortunately when it comes to C# I'm a bit of a noob, and don't even know if this is possible.
Basically what I want is this:
[UIMap.Designer.cs]
partial class myClass
{
public override void myMethod( int a ){ somethingHorrible(int a); };
}
[UIMap.cs]
partial class myClass
{
public sealed override void myMethod( int a ){ somethingNice(int a); };
}
But I know that the sealed and override keywords are usually used with derived subclasses classes, not partial classes. Is this possible? If not then what would be my best alternatives?
There's only one class here - myClass. The partial keyword just allows the class definition to be split across multiple files.
You can use partial methods, but only if the original (generated) method uses the partial keyword. You cannot override a method on the same class.
See Partial Classes and Methods (C# Programming Guide).
If you have no control over the auto-generation itself (ie. a framework or 3rd party generator) your options are somewhat limited. The two approaches that come to mind are to modify the generated code--which as you noted is not practical for changes that are significant and perhaps accumulating over time--and/or to create a derived class and use that instead of using the auto-generated class directly (assuming you control the code which would be using them, which seems likely).
A derived class (inheriting the auto-generated class) would be able to use override or new in the method declarations you want to replace. However, there are a lot of caveats to this approach as well. You can only "override" a method that was delcared as virtual in the base class (or was itself an override of another underlying virtual base, etc). You can also replace a method with a "new" one in the derived class, but the other code in the base class will not know about your "new" version and will not call it (whereas they will call your "override" because they know the method to be virtual). There are also issues of accessiblity; your derived class won't have access to private members of the base class.
But for some set of things you want to do it could work. In some cases you might have to tweak the auto-generated code slightly such as adding the keyword "virtual" or changing "private" members to "protected" so that you can access them from your derived class.
Added: Of course, you can also add new members to the original generated class in your own permanent file for the same partial class, and this code would have access to the class's private members. That can be another way to give your derived class access to the private members, such as by creating a protected property to wrap access to a private member field. If you didn't need to make changes to existing methods you wouldn't necessarily need to create a derived class, but your example talked about wanting to "override" methods from the auto-generated code, so presumably they already exist there.
Also note that a Designer file--such as for a Form or UserControl--does not usally get completely overwritten, so cautious changes outside the core generated code (eg. not inside the "Windows Form Designer generated code" region) can be made (and are persisted). For example, it is sometimes necessary to add a call to your own custom clean-up method in the Dispose(...) method in the Designer file.
When overriding a method should my custom code come before or after the super(base) call to the parent class?
There are 3 choices you have here:
If you want to execute the base behavior before your code, then call it before.
If you want to execute the base behavior after your code, then call it after.
If you want to completely override the base behavior, don't call it at all.
It is important to also check your API's documentation. Some classes have subclass contracts that are not enforcable by code, but that can break behavior if you don't follow their rules. There are some cases where subclasses are required to call the super implementation.
This will depend on when you want your code to execute: before or after the base method.
It depends on You want to make something before or after orginal method. Good practise is to write custom code after super call. That becase you ADD some new code.
It depends of the behavior you want. You don't even have to call super's method at all. The place you call it will depend if you want your code executed before or after the base class code.
Like most things, the simple answer is: it depends.
Specifying super or base allows you to "extend" the method, by adding functionality to what already exists in the base implementation. That code may need to be performed before, after, or on both sides of the call to the base functionality. It all comes down to what your overridden implementation needs to do above and beyond the base implementation.
There are some places, at least in C#, where you cannot choose. For instance, constructors of derived classes in C# have to define a base constructor in their declaration (the default is the parameterless constructor if one exists). The code of the base class is ALWAYS executed BEFORE the derived class, and you can't simply call base(x,y) from within the constructor.
The dependencies of your subclass instance variables with respect to your superclass parameters will determine where your code goes (Java):
private final Baz baz;
public SubClass(Foo foo, Bar bar) {
Qux qux = QuxFactory.getQuxForFoo(foo);
super(bar, qux);
/* getSize() is a method defined on our super class */
baz = BazFactory.getBazOfSize(getSize());
}
I feel like this should be very possible.
I have an interface, let's call it IJerry. Now, I have a class in variable x. That class implements IJerry perfectly. The thing is, that class does not ever reference IJerry. It just happens to have a perfect, compliant signature with IJerry.
Make sense? Let's say you create a class called MyClass that implements INotifyPropertyChanged. Then you delete the MyClass : INotifyPropertyChanged declaration from the class but you LEAVE the implementation inside the class.
Is there a way to determine if the class "implements" an interface even if it does not make an explicit reference to it?
Not easily.
You would have to read the fields, method, and properties of the interface using reflection, and then check if the class has them (again using reflection)
Alternately, if you are using C#4, you could just forget about IJerry, and put MyClass in a dynamic variable, and then you C# figure out at run-time for it has the methods being called.
There's a lot more to implementing an interface than meets the eye. For one, implementation methods are virtual, even though you don't use that keyword. In fact, you're not allowed to use that keyword. For another, the compiler rearranges the methods to match the method table layout of the interface. Removing the inherited interface from the declaration is guaranteed to make the result incompatible. The methods won't be virtual anymore.
What you are pursuing is called 'dynamic dispatch'. Implemented in the DLR and integrated into .NET 4.0 and the C# 4.0 language. Re-inventing the System.Reflection code and making it efficient is a major undertaking.
You would have to use reflection to see if x had methods that matched the ones on IJerry. The real question is, what are you going to do with the answer? Prior to version 4, C# doesn't support "duck typing", so in order to use your class where an IJerry is required you have to write adapter code.
According to MSDN Documentation for partial classes :
Partial methods are implicitly private
So you can have this
// Definition in file1.cs
partial void Method1();
// Implementation in file2.cs
partial void Method1()
{
// method body
}
But you can't have this
// Definition in file1.cs
public partial void Method1();
// Implementation in file2.cs
public partial void Method1()
{
// method body
}
But why is this? Is there some reason the compiler can't handle public partial methods?
Partial methods have to be completely resolvable at compile time. If they are not there at compile time, they are completely missing from the output. The entire reason partial methods work is that removing them has no impact on the API or program flow outside of the one line calling site (which, also, is why they have to return void).
When you add a method to your public API - you're defining a contract for other objects. Since the entire point of a partial method is to make it optional, you'd basically be saying: "I have a contract you can rely on. Oh wait, you can't rely on this method, though."
In order for the public API to be reasonable, the partial method has to really either always be there, or always be gone - in which case it shouldn't be partial.
In theory, the language designers could have changed the way partial methods work, in order to allow this. Instead of removing them from everywhere they were called, they could have implemented them using a stub (ie: a method that does nothing). This would not be as efficient, and is unnecessary for the use case envisioned by partial methods, though.
Instead of asking why are they private, let's rephrase the question to this:
What would happen if partial methods weren't private?
Consider this simple example:
public partial class Calculator
{
public int Divide(int dividend, int divisor)
{
try
{
return dividend / divisor;
}
catch (DivideByZeroException ex)
{
HandleException(ex);
return 0;
}
}
partial void HandleException(ArithmeticException ex);
}
Let's ignore for the moment the question of why we would make this a partial method as opposed to an abstract one (I'll come back to that). What's important is that this compiles - and works correctly - whether the HandleException method is implemented or not. If nobody implements it, this just eats the exception and returns 0.
Now let's change the rules, say that the partial method could be protected:
public partial class Calculator
{
// Snip other methods
// Invalid code
partial protected virtual void HandleException(ArithmeticException ex);
}
public class LoggingCalculator : Calculator
{
protected override virtual void HandleException(ArithmeticException ex)
{
LogException(ex);
base.HandleException(ex);
}
private void LogException(ArithmeticException ex) { ... }
}
We have a bit of a problem here. We've "overridden" the HandleException method, except that there's no method to override yet. And I mean the method literally does not exist, it's not getting compiled at all.
What does it mean what our base Calculator invokes HandleException? Should it invoke the derived (overridden) method? If so, what code does the compiler emit for the base HandleException method? Should it be turned into an abstract method? An empty method? And what happens when the derived method calls base.HandleException? Is this supposed to just do nothing? Raise a MethodNotFoundException? It's really hard to follow the principle of least surprise here; almost anything you do is going to be surprising.
Or maybe nothing should happen when HandleException is invoked, because the base method wasn't implemented. This doesn't seem very intuitive, though. Our derived class has gone and implemented this method and the base class has gone and pulled the rug out from under it without us knowing. I can easily imagine some poor developer pulling his hair out, unable to figure out why his overridden method is never getting executed.
Or maybe this code shouldn't compile at all or should produce a warning. But this has a number of problems of its own. Most importantly, it breaks the contract provided by partial methods, which says that neglecting to implement one should never result in a compiler error. You have a base class which is humming along just fine, and then, by virtue of the fact that someone implemented a totally valid derived class in some completely different part of the application, suddenly your app is broken.
And I haven't even started talking about the possibility of the base and derived classes being in different assemblies. What happens if you reference an assembly with a base class that contains a "public" partial method, and you try to override it in a derived class in another assembly? Is the base method there, or not there? What if, originally, the method was implemented, and we wrote a bunch of code against it, but somebody decided to remove the implementation? The compiler has no way to stub out the partial method calls from referencing classes because as far as the compiler is concerned, that method never existed in the first place. It's not there, it's not in the compiled assembly's IL anymore. So now, simply by removing the implementation of a partial method, which is supposed to have no ill effects, we've gone and broken a whole bunch of dependent code.
Now some people might be saying, "so what, I know that I'm not going to try to do this illegal stuff with partial methods." The thing you have to understand is that partial methods - much like partial classes - are primarily intended to help simplify the task of code generation. It's very unlikely that you would ever want to write a partial method yourself period. With machine-generated code, on the other hand, it's actually fairly likely that consumers of the code will want to "inject" code at various locations, and partial methods provide a clean way of doing this.
And therein lies the problem. If you introduce the possibility of compile-time errors due to partial methods, you've created a situation in which the code generator generates code that doesn't compile. This is a very, very bad situation to be in. Think about what you'd do if your favourite designer tool - say Linq to SQL, or the Winforms or ASP.NET designer, suddenly started producing code that sometimes fails to compile, all because some other programmer created some other class that you've never even seen before that happens to have become a little too intimate with the partial method?
In the end it really boils down to a much simpler question, though: What would public/protected partial methods add that you can't already accomplish with abstract methods? The idea behind partials is that you can put them on concrete classes and they'll still compile. Or rather, they won't compile, but they won't produce an error either, they will just be completely ignored. But if you expect them to be called publicly, then they aren't really "optional" anymore, and if you expect them to be overridden in a derived class, then you might as well just make it abstract or virtual and empty. There isn't really any use for a public or protected partial method, other than to confuse the compiler and the poor bastard trying to make sense of it all.
So instead of opening up that Pandora's box, the team said forget it - public/protected partial methods aren't much use anyway, so just make them private. That way we can keep everything safe and sane. And it is. As long as partial methods stay private, they are easy to understand and worry-free. Let's keep it that way!
Because the MS compiler team did not have a requirement to implement this feature.
Here is a possible scenario of what happen inside MS, because VS uses code gen for a lot of its features, one day a MS code gen developer decided that he/she needed to have partial methods so that the code generated api could be extended by outsiders, and this requirement led the compiler team to act and deliver.
If you don't define the method, what should the compiler do?
If you don't define them, partial methods will not be compiled at all.
This is only possible because the compiler knows where all of the calls to the method are. If the method isn't defined, it will completely remove the lines of code that call the method. (This is also why they can only return void)
If the method is public, this can't work, because the method might be called by a different assembly, which the compiler has no control over.
Reed's and Slak's answers are entirely correct but you seem unwilling to accept their answers.
I will thus try to explain why partial methods are implemented with these restrictions.
Partial methods are for implementing certain sorts of code gen scenarios with maximal efficiency, both in execution time and in meta data overhead.
The last part is the real reason for them since they are attempting to make them (in Erics words) "Pay for play".
When partial methods were added the JIT was entirely capable of inlining an empty method, and thus it having zero runtime effort at the call sites. The problem is that even then there is a cost involved which is that the meta data for the class will have these empty methods increasing their size (needlessly) as well as forcing some more effort during the JITing process to deal with optimizing them away.
Whilst you may not worry too much this cost (and indeed many people won't notice it at all) it does make a big difference to code where startup cost matters, or where disk/memory is constrained. You may have noticed the now mandatory use of .Net on windows mobile 7 and the Zune, in these areas bloat on type metadata is a considerable cost.
Thus partial methods are designed such that, if they are never used they have absolutely zero cost, they cease to exist in the output in any way. This comes with some significant constraints to ensure this does not result in bugs.
Taken from the msdn page with my notes.
...the method must return void.
Partial methods can have ref but not out parameters.
Otherwise removing the call to them may leave you with an undefined problem of what to replace the assignment with.
Partial methods cannot be extern, because the presence of the body determines whether they are defining or implementing.
You can make a delegate to a partial method that has been defined and implemented, but not to a partial method that has only been defined.
These follow from the fact the compiler needs to know if it's defined or not, and thus is safe for removal. This leads us to the one you dislike.
Partial methods are implicitly private, and therefore they cannot be virtual.
Your metal model of this feature is that, if the compiler knows that a partial method is implemented then it should simply allow the partial method to be public (and virtual for that matter) since it can check that you implemented the method.
Were you to change the feature to do this you have two options:
Force all non private partial methods to require implementation.
simple and not likely to involve much effort but then any such methods are no longer partial in the meaningful sense of the original plan.
Any method declared public is simply deleted if it was not implemented in the assembly.
This allows the partial removal to be applied
It requires quite a lot more effort by the compiler (to detect all references to the method rather than simply needing to look in the composed class itself)
The IntelliSense implementation is a bit confused, should the method be shown? sown only when it's been given a definition?
Overload resolution becomes much more complex since you need to decide whether a call to such a method with no definition is either a) a compile time failure or b) results in the selection of the next best option if available.
Side effects within expressions at the call sites are already complex in the private only case. This is mitigated somewhat by the assumption that partial implementations already exhibit a high degree of coupling. This change would increase the potential for coupling.
This has rather complex failure modes in that public methods could be silently deleted by some innocuous change in the original assembly. Other assemblies depending on this one would fail (at compile time) but with a very confusing error (without considerable effort this would apply even to projects in the same solution).
Solution 1 is simply pointless, it adds effort and is of no benefit to the original goals. Worse it may actually hinder the original goals since someone using partial methods this way may not realise they are gaining no reduction in metadata. Also someone may become confused about the errors that result from failing to supply the definition.
That leaves us with solution 2. This solution involves effort (and every feature starts with -100) so it must add some compelling benefit to get it over the -100 (and the additional negatives added for the confusion caused by not the additional edge cases).
What scenarios can you come up with to get things positive?
Your motivating example in the comments above was to "have comments/and or attributes in a different file"
The motivation for XML comments was entirely to increase the locality of documentation and code. If their verbosity is high then outlining exists to mitigate this. My opinion is that this is not sufficient to merit the feature.
The ability to push attributes to a separate location is not in my view that useful, in fact I think having to look in two locations is more confusing. The current private only implementation has this problem too, but it is inevitable and again is mitigated somewhat by the assumption that high coupling that is not visible outside of the class is not as bad as high coupling external to the class.
If you can demonstrate some other compelling reason I'm sure it would be interesting, but the negatives to overcome are considerable.
I've read thorough all your comments and I agree with most of the conclusions, however I have one scenario in which I think will benefit from public/protected partial methods WITHOUT loosing the original intent:
I have a code generator that generates serialization code and other boiler-plate code. In particular, it generates a "Reset" method for every property so that a designer like VS can revert its value to the original. Within the code for this method I generate a call to a partial method Repaint().
The idea is that if the object wants to, it ca write the code for it and then do something, otherwise nothing is done and performance is optimal.
The problem is, sometimes, the Repaint method exists in the object for purposes OTHER than being called from the generated code, at that point, when I declare the method body I should be able to make it internal,protected or public. I am defining the method at this point, and yes, I will documented, etc. here, not in the declaration I generated but in the one I made by hand. The fact that it was also defined in the generated code should not affect this.
I agree that defining access modifiers in a partial method makes no sense when you are declaring the method without a body. When you are declaring the method WITH a body you should be free to declare it any way you want it. I don't see any difference in terms of complexity for the compiler to accept this scenario.
Notice that in partial classes, this is perfectly fine, I can leave one of the partial declarations "naked" without any access modifiers but I can specify them in another partial declaration of the same class. As long as there are no contradictions, everything is fine.
partial methods will be removed by compiler if it doesn't have an implementation. As per my understanding compiler will not be able to remove the partial methods if the methods are accessible as public
//partial class with public modifier
public partial class Sample
{
partial void Display();
}
public partial class Sample
{
partial void Display() { }
}
We will be able to access public methods like below which will be a restriction for compiler to remove the partial method that is not implemented.
// referred partial method which doesn't have implementation
var sample = new Sample();
sample.Display();
The simple reasons is that partial methods are not public because they are an implementation detail. They are meant primarily to support designer related scenarios and are not ever meant to be part of a supported public API. A non-public method works just fine here.
Allowing partial methods to be public is a feature. Features have inherent costs including design, testing, development, etc ... Partial methods were just one of the many features added in a very packed Visual Studio 2008. They were scoped to be as small as possible to fit the scenario in order to leave room for more pressing features such as LINQ.
Not sure if this will answer your question, it did answer mine.
Partial Methods
Excerpts:
If you were allow to return something,
and were in turn using that as a
return value from your CallMyMethods
function, you would run into trouble
when the partial methods were not
implemented.
I've found loads of practical examples of this, and understand the practical output when overriding or hiding methods, but I'm looking for some under the covers info on why this is and why C# allows it when according to the rules of polymorphism, this shouldn't be allowed - at least, insofar as my understanding of polymorphism goes (which seems to coincide with the standard definitions found on Wikipedia/Webopedia).
Class Base
{
public virtual void PrintName()
{
Console.WriteLine("BaseClass");
}
}
Class FirstDerived : Base
{
public override void PrintName()
{
Console.WriteLine("FirstDerived");
}
}
Class SecondDerived : Base
{
public new void PrintName()
{
Console.WriteLine("SecondDerived");
}
}
Using the following code:
FirstDerived b = new FirstDerived();
BaseClass a = b;
b.PrintName();
a.PrintName();
I get:
FirstDerived
FirstDerived
Okay, I get that, makes sense.
SecondDerived c = new SecondDerived();
BaseClass a = c;
c.PrintName();
a.PrintName();
I get:
SecondDerived
BaseClass
Okay, that makes sense, too, instance a can't see c.PrintName() so it's using its own method to print its own name, however I can cast my instance to its true type using:
((SecondDerived)a).PrintName();
or
(a as SecondDerived).PrintName();
to get the output I would expect:
SecondDerived
So what is going on under the covers and what does this mean in terms of polymorphism? I'm told that this facility "breaks polymorphism" - and I guess according to the definition, it does. Is that right? Would an "object oriented" langage like C# really allow you to break one of the core principles of OOP?
(This answers the "why is it allowed" which I think is really the central point of your question. How it works in terms of the IL is less interesting to my mind... let me know if you want me to go into that though. Basically it's just a case of specifying the method to call with a different type token.)
It allows base classes to evolve without breaking derived classes.
Suppose Base didn't originally have the PrintName method. The only way to get at SecondDerived.PrintName would be to have an expression with a static type of SecondDerived, and call it on that. You ship your product, everything is fine.
Now fast forward to Base introducing a PrintName method. This may or may not have the same semantics of SecondDerived.PrintName - it's safest to assume that it doesn't.
Any callers of Base.PrintName know that they're calling the new method - they couldn't have called it before. Any callers which were previously using SecondDerived.PrintName still want to use it though - they don't want to suddenly end up calling Base.PrintName which could do something entirely different.
The difficulty is new callers of SecondDerived.PrintName, who may or may not appreciate that this isn't an override of Base.PrintName. They may be able to notice this from the documentation of course, but it may not be obvious. However, at least we haven't broken existing code.
When SecondDerived is recompiled though, the authors will be made aware that there's now a Base.PrintName class through a warning. They can either stick to their existing non-virtual scheme by adding the new modifier, or make it override the Base.PrintName method. Until they make that decision, they'll keep getting a warning.
Versioning and compatibility isn't usually mentioned in OO theory in my experience, but C# has been designed to try to avoid compatibility nightmares. It doesn't solve the problem completely, but it does a pretty good job.
I answer "how" it works. Jon has answered the "Why" part.
Calls to virtual methods are resolved a bit differently to those of non-virtual ones. Basically, a virtual method declaration introduces a "virtual method slot" in the base class. The slot will hold a pointer to the actual method definition (and the contents will point to an overridden version in the derived classes and no new slot will be created). When the compiler generates code for a virtual method call, it uses the callvirt IL instruction, specifying the method slot to call. The runtime will dispatch the call to the appropriate method. On the other hand, a non-virtual method is called with a call IL instruction, which will be statically resolved to the actual method by the compiler, at compile time (only with the knowledge of the compile-time type of the variable). new modifier does nothing in the compiled code. It essentially tells the C# compiler "Dude, shut up! I'm sure I'm doing the right thing" and turns off the compiler warning.
A new method (actually, any method without an override modifier) will introduce a completely separate chain of methods (new method slot). Note that a new method can be virtual itself. The compiler will look at the static type of the variable when it wants to resolve the method chain and the run time will choose the actual method in that specific chain.
According to the Wikipedia definition:
Type polymorphism in object-oriented
programming is the ability of one
type, A, to appear as and be used like
another type, B
Later on the same page:
Method overriding is where a subclass
replaces the implementation of one or
more of its parent's methods. Neither
method overloading nor method
overriding are by themselves
implementations of polymorphism.
The fact that SecondDerived does not provide an override for the PrintName does not affect its ability to appear and be used as Base. The new method implementation it provides will not be used anywhere an instance of SecondDerived is treated as an instance of the Base; it will be used only when that instance is explicitly used as an instance of SecondDerived.
Moreover, SecondClass can actually explicitly implement the Base.PrintName in addition to the new hiding implementation, thus providing its own override that will be used when treated as Base. (Though, Base has to be an explicit interface definition or has to derive from one to allow this)