How to use partial method in C# to extend existing implemetation - c#

It would be great if this would work. Am I trying to implement my idea in the wrong way?
I would like to use partial method, to be able to extend existing code, and simply plug in/out implementation of methods.
Basically exactly what the reference is stating:
Partial methods enable class designers to provide method hooks,
similar to event handlers, that developers may decide to implement or
not. If the developer does not supply an implementation, the compiler
removes the signature at compile time.
My first try of using this is the following:
DefinitionsBase.cs:
namespace ABC {
public partial class Definitions {
// No implementation
static partial void TestImplementaion();
}
}
DefinitionsExt.cs:
namespace ABC {
public partial class Definitions {
static partial void TestImplementaion(){
// Implementation is here
}
}
}
Program.cs:
namespace ABC {
class Program {
static void Main(string[] args) {
Definitions.TestImplementaion();
}
}
}
It's same namespace, but as reference states partial methods are implicitly private. It doesn't accept access modifiers and I cannot call it from my class. Is there a way to use it as I intend to?
Thanks!

You could use a public method that calls the private method, but I am not sure if this is what you want. This just makes your code work.
Partial methods are by definition private so as during compilation time, in case the method was not implemented, the compiler does not need to go through all of the code, find all possible references to the method, and remove them.
This is a design choice since partial methods do not necessarily need to be implemented, the compiler only looks in the partial class implementation and not throughout all of the code.
If you implement a public method that calls the partial method and the partial method was not implemented, the compiler will still only look in the partial class files and code, even though you have access to that partial method from anywhere in your code.

Related

Why can't I call an extension method from a base class of the extended type‏?

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();
}
}

Use static function from a class without naming the class

How can I access functions from a class without having to name that class every time? I know how to use "using" so that I don't have to name the namespace but I was hoping there was a way to do with this static functions so that I can call them the way I would call a function in the same class.
using static yournamespace.yourclassname;
then call the static class method without class name;
Example:
Class1.cs
namespace WindowsFormsApplication1
{
class Utils
{
public static void Hello()
{
System.Diagnostics.Debug.WriteLine("Hello world!");
}
}
}
Form1.cs
using System.Windows.Forms;
using static WindowsFormsApplication1.Utils;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Hello(); // <====== LOOK HERE
}
}
}
I routinely have
static Action<object> o = s => Console.WriteLine(s);
in my code which makes debug output so much less noisy. That way I can call Console's static Writeline() much easier. Would that help?
If you're looking to define a globally-scoped procedure then the short answer is no, you can't do this in c#. No global functions, procedures or objects.
In C# everything apart from namespaces and types (class, struct, enum, interface) must be defined inside a type. Static members (fields, properties and methods) can be used without an instance of the class, but only by referencing the type that owns them. Non-static members need an instance of the owning class.
This is fundamental to the syntax of the language. C# is neither C nor C++, where you can define global objects, functions and procedures.
In C#? Not possible. Because it's a full OOP programming language and it was designed to work with objects you can't use functions outside the scope of an object. When calling static methods you have to specify the class where that static method lives...
Class.StaticMethod();
you can only use the short-hand notation if this method is call from within the same class...
StaticMethod();
But remember that you will not get access to instance members because static methods donot belong to instance of an object
Update based on comment
Looks like it will be possible to call static members without having to specify the class that declares it in C# 6, and you will be able to reference classes directly in using statements...in similar fashion to Java...more info here

access methods from plain code files and call it in main class (like php include)

This was a general question asked by a colleague of mine....
Is it possible to "outsource" code, and then call it in the main class (e.g. Form1.cs)?
This originates from the fact that he wants to organize his amount of code better than with regions, in the main class.
My first thought was - of course it is!
Use static Extentions, reference it to the main class, and call it through this.Method().
But he meant something like the "include" pattern in PHP....
Is that even possible?
he wants to organize his amount of code better than with regions, in the main class.
You can use partial classes to split the implementation of a single class into multiple (and perhaps more manageable) source files.
In File1.cs:
public partial class MyClass {
public void F() { ... }
}
In File2.cs:
public partial class MyClass {
public void G() { ... }
}
MyClass now has two methods, F and G.
You can externalize using partial classes or decouple it using c# assembly (dll).

Can partial class access static methods in C#?

The tutorial application, MusicStore -MVC3 (92 PageNo), created a POCO class like:
public partial class ShoppingCart
{
MusicStoreEntities storeDB = new MusicStoreEntities();
public static ShoppingCart GetCart(HttpContextBase context)
{
var cart = new ShoppingCart();
cart.ShoppingCartId = cart.GetCartId(context);
return cart;
}
}
How can we access static method in partial classes? In my opinion, we cannot access static methods in a partial class. The partial attribute means other parts of the class will be included in the namespace. In this scenario, I do not know where this other partial class is implemented.
My questions about this static method are:
Can we access static methods in partial classes? If so, how?
Where is this partial class implemented in this MusicStore application? I am not able to find the other part of this class's implementation.
Updated: There is no other ShoppingCart class in the models directory. Does anyone know where that partial implementation would be?
A partial class in C# can definitely access static methods. The partial attribute simply says a class can (not must) be defined accross multiple files and otherwise doesn't affect member lookup.
EDIT Responding to comment in question
A possible explanation for why you can't find the other implementation of ShoppingCart is it may not exist. A partial class is not required to have multiple definitions. The partial only means there may be other parts of the definition.
Yes, you can access static methods in partial classes.
Partial classes are just a way of representing a regular class in multiple source files, often with some of those source files controlled (or generated) by tools.
You can call ShoppingCart.GetCart(context) anywhere - it's a normal public static method.
It's still not really clear what your second question means, but there doesn't have to be another part at all. It's fine (though unusual) to have a partial class which is only declared in a single file.

Class Structure w/ LINQ, Partial Classes, and Abstract Classes

I am following the Nerd Dinner tutorial as I'm learning ASP.NET MVC, and I am currently on Step 3: Building the Model. One part of this section discusses how to integrate validation and business rule logic with the model classes. All this makes perfect sense. However, in the case of this source code, the author only validates one class: Dinner.
What I am wondering is, say I have multiple classes that need validation (Dinner, Guest, etc). It doesn't seem smart to me to repeatedly write these two methods in the partial class:
public bool IsValid
{
get { return (GetRuleViolations().Count() == 0); }
}
partial void OnValidate(ChangeAction action)
{
if (!IsValid)
{
throw new ApplicationException("Rule violations prevent saving.");
}
}
What I'm wondering is, can you create an abstract class (because "GetRuleViolations" needs to be implemented separately) and extend a partial class? I'm thinking something like this (based on his example):
public partial class Dinner : Validation {
public IEnumerable<RuleViolation> GetRuleViolations() {
yield break;
}
}
This doesn't "feel" right, but I wanted to check with SO to get opinions of individuals smarter than me on this. I also tested it out, and it seems that the partial keyword on the OnValidate method is causing problems (understandably so). This doesn't seem possible to fix (but I could very well be wrong).
Thanks!
I'm wondering is, can you create an
abstract class ... and extend a
partial class?
Sure, the partial keyword simply indicates that the class is implemented in multiple files - it has no real bearing on inheritance ... except in one narrow respect:
If the partial class contains a
reference to a forward-declared
partial method, but no part of that
class implements that partial method -
all calls to that partial method will
be omitted by the compiler.
So what does this mean. If your partial class declares a partial method in one of it's parts, but no other part of your class defines the partial method - then you can't call that partial method in any derived classes ... since it won't exist.
Let's look at an example:
// file1.cs (code gen'd)
public partial class Validation {
partial void OnValidate(ChangeAction action);
private void SomeMethod() {
OnValidate( ChangeAction.Whatever );
}
}
// file2.cs (Validation class body)
public partial class Validation {
//partial void OnValidate(ChangeAction action) { ... }
}
public class Dinner : Validation {
public void SomeOtherMethod() {
OnValidate(null); // won't compile ... OnValidate doesn't exist
}
}
You should also be aware that partial methods cannot have modifiers (like new, abstract, virtual, public, private, etc). This means you cannot override a partial method in a derived class. You can, however, define a virtual method that a partial method calls.
To your general question, there's nothing wrong with inheriting from partial classes or trying to avoid duplication of code. However, you need to work within the one or two limitations that partial classes/methods impose.
In your example, if you want to avoid duplicating logic, you may need to define your partial methods in the base class to make sure they are always available. Derived classes would not be be able to override them - but if this is needed, then just don't make those methods partial.

Categories

Resources