Do you know the answer to following question?
Let us say, it MyMethod() is declared
as partial method in MyPartialClass in
MyPartialClass.cs. I have also
provided body of MyMethod() in
MyPartialClass in MyPartialClass2.cs.
I use a problem without answer“Magic”
code generator which has actually
generated MyPartialClass.cs, let us
say based on some DB schema. Some
innocent guy changes schema for good
and then runs “Magic”.
MyPartialClass.cs is re-generated but
with MyMethod2() instead of MyMethod()
declaration. Think of me. I am
thinking that I have implemented
MyMethod() which is used by “Magic”
but in reality, “Magic” is using
MyMethod2(). C# compiler does not tell
me that I have partial method
implemented without any declaration
and my implementation is not used at
all!
Any solution?
I think it is a problem without an answer.
EDIT I got an answer :-). I had a typo in my code and that is why compiler was not flagging error. Jon already has pointed that out.
You should get error CS0759. Test case:
partial class MyClass
{
partial void MyMethod()
{
Console.WriteLine("Ow");
}
}
partial class MyClass
{
partial void MyMethod2();
}
Compilation results:
Test.cs(6,18): error CS0759: No defining declaration found for implementing
declaration of partial method 'MyClass.MyMethod()'
Does that not do what you want it to?
In short, no; that is the point of partial methods - the declaring code doesn't need to know whether an implementation is provided or not.
Of course - you could just not declare the partial method: consume it assuming it exists; if you don't provide it, the compiler will complain of a missing method.
There is a hacky way to check at runtime (with partial methods), which is to have the other half update a ref variable:
partial void Foo(ref chk);
partial void Foo(ref chk) { chk++;}
(and verify it changes) - but in general, partial methods are designed to not know if they are called.
Another approach is a base-class with an abstract method - then it is forced by the compiler to be implemented.
This is the whole purpose of partial methods. If the method is not implemented, it is removed without a trace, and without a warning.
One solution to this type of problem would be to use a double derived pattern in your code generation. This is used extensively by DSLTools and is quite powerful.
Write the following code by hand :
public class MyClassBase
{
public abstract void MyMethod();
//Put all other methods required by the class here.
}
public partial class MyClass : MyClassBase
{
//This class is entirely empty!
}
Generate the following code in magic.
public partial class MyClass
{
public void MyMethod(){}
}
If someone fails to implememnt MyMythod() in the generated code, you will get a compiler error.
Related
my question could seem strange.
I use a class to encapsulate a method to not have to build a class of the interface (it's a bit long to explain and i don't want to go too far).
I would to know if it was possible to "extend" a generic class by add partial to "extend" its generic part. The purpose is to keep the same name class, but by add one (or more in the future) generic type to have the possibility to encapsulate any method, then pass the object containing the function and that include this interface.
I need to have:
new Foo<string>()
new Foo<string, int>()
...
I 'successful' made this i think, but perhaps it will generate some bug i can't imagine right now, or perhaps it's not.. how to say a good way to program.
Example:
Original
// A class to encapsulate a method "without parameter"
partial Foo<T>: Interface
{
public Func<Interface, T> FooLambda{ get; set; }
public virtual object Run()
{
return ToRun(this);
}
}
The method i need to pass (from another class)
void FooToEncapsulate(Interface patt)
{
//--- My code using an object with the interface pattern
}
Add another generic Type to Foo
The part to "extend" Foo
partial Foo<T,Y>: Foo<Y>
{
public new Func<Interface, T, Y> FooLambda{ get; set; }
public T Param {get;set;}
public override object Run()
{
return this.ToRun(this, Param);
}
}
The other method i need to pass (from another class)
void FooToEncaspulate(Interface patt, int param)
{
//--- My code using an object with the interface pattern
//--- and "param"
}
I have no problem for the while with this code, and i know it's something that could be strange, must i forget to use this technic, or could i think it was thought to work also like this ? Must i think if it compiles that means it's ok ? Is there another way to proceed like this without create a new class, and extend in same time on the generic part ?
(Sorry for my english)
Thx.
Edit:
I thought by using partial that could be a good idea, because i would to keep the same name for my class. After have read an answer and comment from Enigmativity, i tried without partial, and i have no errors relating to the name of the class when i compile.
If i well understand, the fact to add generic parameter to a class makes that create as many class than as "variants" depending on the generic type. "Partial" is useful to split code on several files on a basic class.
Is partial could be useful on code split with the same number of generic type ?
You don't need the word partial to extend a class with a single generic type to have two generic types. They are in fact two distinct classed.
This works fine:
class Foo<T>
{
}
class Foo<T, Y> : Foo<Y>
{
}
Now, as said in the comments, the rest of your code is quite flaky. If you can clean up the code I could provide you with a more answer that will be of more use to you.
I am working on a Visual Studio 2015 project from another developer using his previous solution file (.sln). It has two assemblies, one which contains the class with the main method and the other which contains a single worker class. Within the class there is currently one method. If I add another public method (examples below) I cannot call that method from the first or any other method I write for the class. It seems there is something set in this project that is not allowing me to do this. If I start a new project everything works normally.
Here is a scaled down example of what is happening.
namespace MyPoject
{
public class MyClass1
{
public void MyMethod1()
{
Console.WriteLine("TEST");
}
public void MyMethod2()
{
//This does not work/complete with intelesense
//Error is "MyClass1.MyMethod1() must declare a body because it is not marked abstract, extern or partial.
MyMethod1();
}
public void MyMethod3()
{
//Nor can I use this
//Error is Invalid token 'this' in class, struct, or interface member declaration
this.MyMethod1();
}
}
}
Any help would be greatly appreciated as the the class is fairly large and I'd rather not recreate the whole project. If instead of adding a method to the class I create another class then instantiate it I can call methods within that object which does solve the problem but I hate when something doesn't work the way I expect it to so I'd love to solve this issue.
I have Capture class as follow:-
namespace FrontEnd
{
public partial class Capture : Window, DPFP.Capture.EventHandler
{
public Capture()
{
InitializeComponent();
}
protected virtual void init()
{
try
{
if (null != cap)
cap.EventHandler = this;
else
SetPrompt("Cannot Use the Device right now");
}
catch { MessageBox.Show("Cannot Use the Device right now"); }
}
}
}
I have Enrollment class as follow:-
namespace FrontEnd
{
public partial class Enrollment : Capture
{
protected override void init()
{
base.Init();
Enroller = new DPFP.Processing.Enrollment();
UpdateStatus();
}
}
}
I am getting three errors in Enrollment.cs:
1 - Partial declarations of 'Enrollment' must not specify different base classes.
2 - 'Enrollment.init()': No suitable method found to override.
3 - The name 'UpdateStatus' does not exist in current context.
I dont know where the problem exactly lies. Perhaps it is in the inheritance. Moreover, i am using WPF, so it might be possible that i am supposed to change xaml code as well in order to undergo inheritance.
Kindly help in resolving these errors.
I am pretty sure that like JAVA, multiple inheritance is also not allowed in C# as well. And for the class Capture you are inheriting from two classes.
public partial class Capture : Window, DPFP.Capture.EventHandler
There can be a work around for that. You can use multilevel inheritance. That will resolve the issue.
1 - Partial declarations of 'Enrollment' must not specify different base classes.
My first guess on this case would be, that you have another class that is also partial and derives from a different class than Capture.
2 - 'Enrollment.init()': No suitable method found to override.
The problem here is, that the base classes Capture, Window and Eventhandler do not define the init() method so you cannot override it. If you remove the override from the init method you should be good to go.
Probably the issue is a simple typo. In this method you call a Init() method and the override is a lower case init
3 - The name 'UpdateStatus' does not exist in current context.
Same issue like in 2. There is no UpdateStatus in the base class.
I also think, that it is an issue to derive from multiple classes becaus like java , c# does not support multiple inheritance.
Somewhere else in your code you have another class called FrontEnd.Enrollment. This will derive from something other than Capture. This is causing error 1.
Because the compiler cannot tell what the correct base class is you will not be able to resolve any members of that class. This is causing errors 2 & 3
So correct the issue with the multiple base classes and you'll be fine.
I'm trying add the ability to lookup elements in a List<KeyValuePair<string,int>> by overriding the indexer.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
public class MyList : List<KeyValuePair<string, int>>
{
public int this[string key]
{
get
{
return base.Single(item => item.Key == key).Value;
}
}
}
}
For some reason, the compiler is throwing this error:
'System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<string,int>>' does not contain a definition for 'Single'.
While it is true that List<T> doesn't have that method, it should be visible because it is an extension method from the System.Linq namespace (which is included). Obviously using this.Single resolves the issue, but why is access via base an error?
Section 7.6.8 of the C# spec says
When base.I occurs in a class or struct, I must denote a member of the base class of that class or struct.
Which might seem to preclude access to extension method via base. However it also says
At binding-time, base-access expressions of the form base.I and base[E] are evaluated exactly as if they were written ((B)this).I and ((B)this)[E], where B is the base class of the class or struct in which the construct occurs. Thus, base.I and base[E] correspond to this.I and this[E], except this is viewed as an instance of the base class.
If base.I is just like ((B)this).I then it seems like extension methods should be allowed here.
Can anyone explain the apparent contradiction in these two statements?
Consider this situation:
public class Base
{
public void BaseMethod()
{
}
}
public class Sub : Base
{
public void SubMethod()
{
}
}
public static class Extensions
{
public static void ExtensionMethod(this Base #base) { }
}
Here are some interesting assertions about this code:
I cannot call the extension method using ExtensionMethod() from neither Base nor Sub.
I cannot call base.ExtensionMethod() from Sub.
I can call the extension method using Extensions.ExtensionMethod(this) from both Sub and Base.
I can call the extension method using this.ExtensionMethod() from both Sub and Base.
Why is this?
I don't have a conclusive answer, partly because there might not be one: as you can read in this thread, you have to add this. if you want to call it in the extension method style.
When you're trying to use an extension method from the type it is in (or - consequently - from a type that is derived from the type used in the extension method), the compiler doesn't realize this and will try to call it as a static method without any arguments.
As the answer states: they [the language designers] felt it was not an important use case scenario to support implicit extension methods (to give the beast a name) from within the type because it would encourage extension methods that really should be instance methods and it was considered plain unnecessary.
Now, it is hard to find out what is happening exactly under the covers but from some playing around we can deduce that base.X() does not help us. I can only assume that base.X performs its virtual call as X() and not this.X() from the context of the baseclass.
What do I do when I want to call the extension method of a baseclass from a subclass?
Frankly, I haven't found any truly elegant solution. Consider this scenario:
public class Base
{
protected void BaseMethod()
{
this.ExtensionMethod();
}
}
public class Sub : Base
{
public void SubMethod()
{
// What comes here?
}
}
public static class Extensions
{
public static void ExtensionMethod(this Base #base)
{
Console.WriteLine ("base");
}
public static void ExtensionMethod(this Sub sub)
{
Console.WriteLine ("sub");
}
}
There are 3 ways (leaving aside reflection) to call the ExtensionMethod(Base) overload:
Calling BaseMethod() which forms a proxy between the subclass and the extensionmethod.
You can use BaseMethod(), base.BaseMethod() and this.BaseMethod() for this since now you're just dealing with a normal instance method which in its turn will invoke the extension method. This is a fairly okay solution since you're not polluting the public API but you also have to provide a separate method to do something that should have been accessible in the context in the first place.
Using the extension method as a static method
You can also use the primitive way of writing an extension method by skipping the syntactic sugar and going straight to what it will be compiled as. Now you can pass in a parameter so the compiler doesn't get all confused. Obviously we'll pass a casted version of the current instance so we're targetting the correct overload:
Extensions.ExtensionMethod((Base) this);
Use the - what should be identical translation - of base.ExtensionMethod()
This is inspired by #Mike z's remark about the language spec which says the following:
At binding-time, base-access expressions of the form base.I and base[E] are evaluated exactly as if they were written ((B)this).I and ((B)this)[E], where B is the base class of the class or struct in which the construct occurs. Thus, base.I and base[E] correspond to this.I and this[E], except this is viewed as an instance of the base class.
The spec literally says that base.I will be invoked as ((B) this).I. However in our situation, base.ExtensionMethod(); will throw a compilation error while ((Base) this).ExtensionMethod(); will work perfectly.
It looks like something is wrong either in the documentation or in the compiler but that conclusion should be drawn by someone with deeper knowledge in the matter (paging Dr. Lippert).
Isn't this confusing?
Yes, I would say it is. It kind of feels like a black hole within the C# spec: practically everything works flawlessly but then suddenly you have to jump through some hoops because the compiler doesn't know to inject the current instance in the method call in this scenario.
In fact, intellisense is confused about this situation as well:
We have already determined that that call can never work, yet intellisense believes it might. Also notice how it adds "using PortableClassLibrary" behind the name, indicating that a using directive will be added. This is impossible because the current namespace is in fact PortableClassLibrary. But of course when you actually add that method call:
and everything doesn't work as expected.
Perhaps a conclusion?
The main conclusion is simple: it would have been nice if this niche usage of extension methods would be supported. The main argument for not implementing it was because it would encourage people to write extension methods instead of instance methods.
The obvious problem here is of course that you might not always have access to the base class which makes extension methods a must but by the current implementation it is not possible.
Or, as we've seen, not possibly with the cute syntax.
Try to cast the instance to its base class:
((BaseClass)this).ExtensionMethod()
Applied to your code:
public class Base
{
public void BaseMethod()
{
}
}
public static class BaseExtensions
{
public static void ExtensionMethod(this Base baseObj) { }
}
public class Sub : Base
{
public void SubMethod()
{
( (Base) this).ExtensionMethod();
}
}
I have just one method that I need several different classes to access and it just seems lame to make a utility class for just one method. The classes that need to use this method are already inheriting an abstract class so I can't use inheritance. What would you guys do in this situation?
[I]t just seems lame to make a utility
class for just one method
Just do it, it will grow. It always does. Common.Utilities or something of that nature is always necessary in any non-trivial solution.
Keep in mind that a class is just a small, focused machine. If the class only has one method then it's just a very small, focused machine. There's nothing wrong with it, and centralizing the code is valuable.
There is a cheat that you can use :-)
Create an Interface that your classes can "implement" but, create an extension method on that interface, your classes then magically get that method without having to call the utility class...
public Interface IDoThisThing {}
public static void DoThisThingImpl(this IDoThisThing dtt)
{
//The Impl of Do this thing....
}
Now on your classes you can just add the IDoThisThing
public class MyClass, MyBaseClass, IDoThisThing
{
//...
}
and they Get that thing :-)
Note, this is only syntatic sugar around effectively a utility class, but it does make the client code very clean (as just appears as a method on your class).
What do you mean you can't use inheritance?
If you write the method in the abstract class, you can also write the implementation (not everything in an abstract class needs to be abstract).
But generally, it's advisable to have some sort of 'GeneralUtils' class; cause you end up with a few of these functions.
I'd need more info to give a definite answer.
However a well-named class with a single well-named method could work wonders for readability (as compared to an inheritance based solution for instance)
Since you use the term utility method, I'd say create a static class with the static method and be done with it.
can use extension methods...
namespace ExtendMe
{
public interface IDecorate { }
public static class Extensions
{
public static void CommonMethod(this IDecorate o) { /* do stuff */ }
}
public class Blah :IDecorate {}
public class Widget : IDecorate {}
class Program
{
static void Main(string[] args)
{
new Blah().CommonMethod();
new Widget().CommonMethod();
}
}
}