Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I am new to C# and I found this documentation and example about events in C#:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/events/how-to-publish-events-that-conform-to-net-framework-guidelines
For me especially these lines are of interest:
public void DoSomething()
{
// Write some code that does something useful here
// then raise the event. You can also raise an event
// before you execute a block of code.
OnRaiseCustomEvent(new CustomEventArgs("Event triggered"));
}
// Wrap event invocations inside a protected virtual method
// to allow derived classes to override the event invocation behavior
protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
{
// Make a temporary copy of the event to avoid possibility of
// a race condition if the last subscriber unsubscribes
// immediately after the null check and before the event is raised.
EventHandler<CustomEventArgs> raiseEvent = RaiseCustomEvent;
// Event will be null if there are no subscribers
if (raiseEvent != null)
{
// Format the string to send inside the CustomEventArgs parameter
e.Message += $" at {DateTime.Now}";
// Call to raise the event.
raiseEvent(this, e);
}
}
For me this naming does not make sense at all or I did not understand how the events work in C#. If I am not wrong then in DoSomething the CustomEvent is triggered. But normally onAnything functions are listening on events. Do you also think that OnRaiseCustomEvent should be named RaiseCustomEvent?
That is the c# naming convention.
You don't have to agree with it, but you should be familiar with it and I would also recommend using it in your code.
An experienced c# programmer that will see a method called On<blabla> that take in an argument named EventArgs or anything that ends with the suffix EventArgs (like <blabla>EventArgs) will immediately expect this method to raise an event called <blabla>.
(Naturally, <blabla> is just a placeholder for an actual name)
This pattern exists because while events are being inherited, the only way to raise them is within the declaring type - as documented in How to raise base class events in derived classes (C# Programming Guide):
... events are a special type of delegate that can only be invoked from within the class that declared them. Derived classes cannot directly invoke events that are declared within the base class.
This is why you need the On<blabla>(BlaBlaEventArgs e) method to be protected virtual (unless your class is declared as sealed) - so that it's derived classes will be able to raise the <blabla> event as well.
Official documentation also admits that (at least some of) the names chosen in this pattern are somewhat misleading - as mentioned here:
The name EventHandler can lead to a bit of confusion as it doesn't actually handle the event.
Personally, I think they might have chosen better names for this as well as for the On<blabla> methods, but it's way, way too late to change it now.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I want to pass a parameter into a method only for the purposes of logging. The parameter is a type of an event that I'm about to process. I can see two approaches to this, and I'm wondering if either of them is more correct?
private void LogEventProcessing<T>()
{
_logger.Information($"Started processing of {typeof(T).Name} event");
}
private void LogEventProcessing(Type type)
{
_logger.Information($"Started processing of {type.Name} event");
}
Using Type parameters is cleaner, there's close Flags being placed on this question that I don't agree with, the reason being that the first is the better choice in the scenario described.
You can use Type Constraints to constrain the Type of the parameter being inserted by the client.
private void LogEventProcessing<T>() where T : Event
{
_logger.Information($"Started processing of {typeof(T).Name} event");
}
The above method will now only accept classes that inherit from the type Event, it's cleaner, and makes the expectation clear to the client what you're expecting here.
I don't like either of these options. As a client you either have to use reflection to call the generic version or you have to call GetType() on the event before passing it to a logging function. That just seems like your client is too closely coupled with what the logging function is doing. What happens if it wants to log more information about the event? Do you create a new method and pass just that information? Or do you go back to every reference to this method and add a new parameter?
Yuck, either way, yuck. My advice: Don't do either. Pass the event and then get whatever you need from it in the method itself.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I want to recall a method from the called method, can i use action for that, or any other solution.
I see some ambiguity in your question use case..
Let us take a simple use case: You want to call some one and they in turn call you back. Is there any use to it and when do you want to stop this and go ahead to get some work done?!
For example following code like what you are expecting will go in infinite recursion and result in StackOverflowException
class MyClass
{
public void TargetMethod(Action callback)
{
Console.WriteLine("Inside TargetMethod");
callback(); //This call the SourceMethod() and which inturn call TargetMethod() again in infinite recursion.
}
public void SourceMethod()
{
Console.WriteLine("Inside SourceMethod");
TargetMethod(SourceMethod);
}
}
//Calling code
MyClass objMyClass = new MyClass();
objMyClass.SourceMethod();
Instead you can use Callback mechanism, so that once you done within the target method, notify another handler method that in turn can do some stuff like logging or updating UI etc., case specific stuff.
class MyClass
{
public void TargetMethod(Action callback)
{
Console.WriteLine("Inside TargetMethod");
callback(); //This calls/notify the handler to do some stuff.
}
public void SourceMethod()
{
Console.WriteLine("Inside SourceMethod");
TargetMethod(CallbackHandler); //Notice here we are calling to a handler which can do some stuff for us.
}
public void CallbackHandler()
{
Console.WriteLine("Inside CallbackHandler");
}
}
This code is just for quick demonstration purpose and you can enhance design further in your implementation.
Hope this provide you some heads-up on why you need to revisit your design..
You should not do this in normal situations, your design is probably wrong!
You can use the CallerInfoAttribute to get the caller and use reflection to invoke it.
But... that is a lot of work and I think you are not very skilled. Luckily, there is another way!
You can add a parameter of type MethodInfo. And let's say A() calls B(MethodInfo). Then A needs to get its reflected self and pass it into B. Then in B you can use MethodInfo.Invoke to invoke the method.
Well... it turns out that the alternative requires reflection too... So if you are not familiar with reflection, learn more about it first!
If you want to know more about MethodInfo, go to here: https://msdn.microsoft.com/en-us/library/system.reflection.methodinfo(v=vs.110).aspx
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
What's best practice for preventing delegates from causing memory leaks? For event handlers I would just call -= for each registered handler. I have my delegate assigned with a '=' (equals sign). Shall I just assign NULL at dispose time?
public delegate int MyDelegate(string message);
public class MyManager MyDelegate
{
public MyDelegate ManagerDelegate;
..
public class Transaction
{
public int DoSomething(string message)
{
//do something
}
public void init()
{
var manager = new MyManager();
manager.ManagerDelegate = this.DoSomething("abc");
An instance delegate references a class instance (in its Target property), so if you store that delegate somewhere, whether an event or a simple delegate typed property, that will reference your original class. In this respect, it doesn't matter if it's an event or not. So if you want to have your original class garbage collected while the other class stays alive, you have to clean up. Remove your event handlers and also any other delegates. If the other class dies first, your original class can die, too, so it depends on your specific case.
Update: proof: http://pastebin.com/XcTz76dY
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have a problem with a example of my book. From what i have read non static methods cant be used without instance a object of the class. So is this ok ?
public partial class TempAgencyForm : Form
{
public TempAgencyForm()
{
InitializeComponent();
}
private void btnCalculate_Click(object sender, EventArgs e)
{
...
setVisibility(false);
}
private void setVisibility(bool visibilityValue)
{
...
}
}
Yes, it is fine. One non-static method can call another non-static method.
The call:
setVisibility(false);
can also be written:
this.setVisibility(false);
but the this qualifier is redundant.
However, if you had tried to call a non-static method without instance qualification from inside a static member, that would have been a problem (compile-time error).
I assume you are talking about calling setVisibility(false);. Yes it is fine, neither it or the method calling it are static.
This will all happen within an instance of TempAgencyForm
Yes this is okay, because it's called from within another member.
You're correct, since setVisibility() is not static, it always has to be called in the context of some object of the parent class (TempAgencyForm in this example).
However, btnCalculate_Click() is another member of TempAgencyForm, as such you're able to access the current/local object using the this keyword (this.setVisibility()), which is optional if there's no disambiguity.
static or non static doesnt matter here, you are calling a member function declared within the same object. so short answer is "fine"
how you call TempAgencyForm members may be what you are referring to
in this case (as you have defined) instantiations is required
TempAgencyForm taf = new TempAgencyForm()
taf.setVisibility(false);
however if you have your class definition itself as static, i.e.
public static partial class TempAgencyForm
then,
TempAgencyForm.setVisibility(false);
is suffice (without instantiating the object) as the object is already loaded on stack at the time of application start
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
How can I implement one? Will it work across multiple assemblies? If not, how can I make it work?
At the risk of not understanding the question fully, I would like to offer another possible explanation.
Talking about classes, Java has an EventListener and .NET has an EventHandler. Both have the same purpose: event handling. However there are differences in implementation. It could be said that .NET's event handling is a higher level of abstraction to Java's event listeners.
The Java's EventListener is "a tagging interface that all event listener interfaces must extend" (i.e. MouseListener). The .NET's EventHandler is a delegate, a strongly typed pointer to a method that handles an event.
More broadly, an event listener is an object that implements an interface for event handling while an event handler is just a method that handles an event. Generally speaking, event listeners implements an Observer Design Pattern and event handlers hide all the plumbing of that pattern. Therefore writing an event listener is much more involved and tends to be more verbal than writing an event handler.
I would recommend to read the Observer Design Pattern by Microsoft to get a better understanding of it.
So, to implement an event handler you simply assign a delegate to the event of an object you want to handle. I.e.
Button.Click += new EventHandler(MyButton_Click);
where MyButton_Click is a method (it could be in your class or somewhere else) that has the EventHandler's signature and actually handles the event, i.e.
private void MyButton_Click(object sender, EventArgs e)
{
doSomething();
}
To achieve the same with event listeners in Java, you would write something like this (pardon me if I'm making mistakes, since I'm writing it from memory):
public class MyClass
{
Button myButton;
MyClass()
{
...
myButton.addMouseListener(new ButtonHandler());
}
public class ButtonHandler implements MouseListener
{
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e)
{
doSomething("Mouse clicked", e);
}
}
}
Naturally, there are many ways to implement this common observer pattern, including implementing EventListener interfaces in the class itself, in inner classes, in anonymous classes, in adapters, etc. But this should demonstrate the point.