I know this question has been asked many times in many forms, but now I want to clarify a few things.
2 methods: default method and additional method. First we perform default method with basic operations. Then, if additional method was passed to the default method as the parameter, perform it too.
???void Default_Method(???Additional_Method)
{
//default logic
//after default logic, call additional method if its name was specified
??? - how to call the specified additional method
}
???void Additional_Method()
{
//additional logic
}
...
And now the most interesting place
protected void Page_Load(object sender, EventArgs e)
{
Default_Method(???Additionl_Method???) //here I need to pass Additional_Method as a parameter
}
THE QUESTION:
How to declare the methods properly. I marked places to clarify with ??? mark.
And how to make the additional method be an optional parameter of the default method? Is it enough to pass Null when it is not needed?
REASON FOR THIS QUESTION
I didn't find a general instruction on how to do it. All examples are full of individual specifics, people use their own understanding when give names to methods and it is not really clear which one does what in their examples, that's why I decided to create the thread with neutral names.
void Default_Method(Action additionalMethod = null)
{
//default logic
//after default logic, call additional method if its name was specified
//This if is needed to avoid NullReferenceException
if (additionalMethod != null)
additionalMethod();
}
void Additional_Method()
{
//additional logic
}
protected void Page_Load(object sender, EventArgs e)
{
Default_Method(Additional_Method);
//OR
Default_Method();
//OR
Default_Method(null);
//OR
Default_Method(() => { /*Do something*/});
}
In this example I assumed that both methods are defined in the same class as Page_Load.
IMHO best to use an Action:
void Additional_Method()
{
}
void Default_Method(Action a)
{
a.Invoke();
}
in your main code use
Default_Method(Additional_Method);
Related
I would like to call an event having parameters from another event, both have different namespaces, is it passable to do this?
public void event1(object1 sender, eventArgs e1)
{
// code goes here
}
public void event2(object2 sender, eventArgs e2)
{
// here I want call event1 with parametersenter code here
}
is it possible?
The best way to do this is not in terms of events being called but just methods being called.
If in the simplest terms your events just called Method1 and Method2 respectively then you could easily have Method1 call Method2 and do whatever it does.
You could raise potentially raise event1 from inside event2 but it doesn't necessarily make sense to do so (for example if it is a click event it should only be raised by a click. It is best to just refactor common code into a method that can be easily called using standard OOP techniques. In my code below I've made the extracted methods static methods so they are easier to call from other objects and assumed that Method1 is in Class1 (not explicitly shown) which is in Namespace1. You may need to do things slightly differently if you need them to be non-static methods.
Here's the example of what I mean.
public void event1(object1 sender, eventArgs e1)
{
var myParameter = ...;
Method1(myParameter);
}
public static void Method1(object myParameter)
{
// code goes here
}
public void event2(object2 sender, eventArgs e2)
{
var myParameter = ...;
Method2(myParameter);
}
public static void Method2(object myParameter)
{
Namespace1.Class1.Method1(myParameter);
}
Using "MyNameSpace";
thats all you need.
I need to write 30 characters so
include "mynamespace" for c++.
Unless i misunderstood what you meant.
I came across the following situation.
I have a lot of class files in my project, and, as the project was growing, new functions were being created, but without the correct code review. So, we have some duplicated objects (to access the database, like a controller) being created around the same class, but we don't know if it is better to create only one global object or if we should leave them inside the function, because sometimes the code will not reaches that function, so the object will never be created. If it is global, it will be created every time.
Example:
namespace EventWorks.View
{
public partial class Event : System.Web.UI.Page, ISecurityRules
{
protected void btnNew_Click(object sender, EventArgs e)
{
EventController EventCtrl = new EventController();
//some code
}
protected void btnSave_Click(object sender, EventArgs e)
{
EventController EventCtrl = new EventController();
//some code
}
}
}
My question is, where should I create these objects? It's better to create it globally? Or leave it inside the function and let the garbage collector take care of it? Or make a big analysis and check for every file which option is better?
where should I create these objects?
That really depends on the responsibility of the object, the thread-safety considerations (if there are any), and cost of creating such a global member. There is no "yes make it global" solution to all your problems. You should definitely analyze all your members and decide for each one if it is OK to make them globally available and what effects it would have on your system. For example, keeping a DbContext alive in memory as a single instance would be considered bad practice, since it isn't thread-safe.
If you're only worried about unnecessary objects being created, you can always use the Lazy<T> class which will make sure the value is only lazily initialized on the first access:
private readonly Lazy<EventController> eventController = new
Lazy<EventController>(x => new EventController(), isThreadSafe: true);
If used in multiple functions it can be declared on class level like this (thats not global, but class level):
namespace EventWorks.View
{
public partial class Event : System.Web.UI.Page, ISecurityRules
{
EventController _eventController = new EventController();
protected void btnNew_Click(object sender, EventArgs e)
{
_eventController.DoSomething();
}
protected void btnSave_Click(object sender, EventArgs e)
{
_eventController.DoSomething();
}
}
}
It can be initiliased in constructor also, or it can be injected via dependency injection (Constructor, Interface, setter injection), I guess it all depends what you want.
Often a controller keeps some information on the object status. I.e., whether the object is new or whether it has been loaded from a DB, whether it has pending changes or not and so on.
Therefore it seems more logical to have a controller that has the same life-time as the object (it would be created once per object).
If the controller does not store any object dependent stuff, it could be created once per application lifetime. In this case you could make it a singleton.
public class EventController
{
public static readonly EventController Instance = new EventController();
private EventController()
{
// Make constuctor private, so the class cannot be instantiated elsewhere.
}
// Implement functionality here...
}
call it like this:
EventController.Instance.DoSomething();
I'm developing a program that scrapes content from various online archives, but am new to OOP. The way I believe would work best would be to have a parent class that specifies the shared variables and methods, then a child class for each archive which then contains the specific methods for grabbing info from that particular site, such as GrabStoryVariables() existing in each child class to accommodate the individual needs of that archive. The program takes a URL in a textbox, and then from there it will determine using the URL which child class to instantiate.
The problem I'm having is figuring out how to create the child class object and make it accessible to the entire program. For example, to create an instance of FanFictionAuthors : FanBook:
private void btnGetInfo(object sender, EventArgs e)
{
CreateBook();
}
private void CreateBook()
{
if (addressBar.Text.Contains("fanficauthors.net"))
{
FanFictionAuthors myBook = new FanFictionAuthors();
}
return;
}
The scope of myBook is just the CreateBook() function, so this approach won't do the trick. Any suggestions on the best way to handle this issue? I'm using this as an approach to better learn programming, so the "correct" way is what I'm trying to figure out, whatever that is.
Edit: The specific function of the program is to take a provided URL for an online story from fanfiction.net, fictionpress.com, or one of any number of other online story archives. There are a set of shared attributes each story will have, such as title, number of chapters, length in words, chapter titles, and the actual content of the story. The program compiles all of this to create a single html document (later to be expanded to allow for different ebook formats) rather than a bunch of small individual chapter files.
With that in mind, the only parts that should differ between each archive are the methods for grabbing the variables from the particular archive and how to iterate between the chapters based on the archive's function for that.
Currently what I'm doing is just creating a myBook object immediately upon launching the main form, then creating a different method name for the functions that grab the variables and do the iteration. As I add more archives, however, this becomes more complicated. What I originally wanted to do was to just cast the myBook to the individual archive types (FanFictionAuthors in this case) to grab the ability to use their specific functions. Looking online, it appears casting from parent to child isn't easy nor recommended, so I'm not sure how else to approach this.
Here's the GitHub link for the project. This version is slightly out of date, but lets you see how I'm currently approaching this: https://github.com/benroth/fBook
Create a super class where you common attributes and methods in there:
public class FanBook
{
// use a common constructor
public FanBook(string url)
{
grabHtml(url);
// ...
}
protected string grabHtml(string address) { // SNIP }
protected void CreateStoryHeader() { // SNIP }
// other common methods which are the same for every subclass (maybe BuildToc, GetStory, etc.)
// maybe if you want some easy access to attributes, you could add a dictionary
public void Dictionary<string, string> Attributes;
// Then use abstract methods to define methods that are different for subclasses
protected abstract void GrabStoryVariables();
protected abstract void GenerateStoryInfo();
}
Then create a subclass that derives from Book:
public class FFNETBook : FanBook {
// FFNETBook constructor to call contructor from FanBook too
public FFNETBook(string url) : FanBook(url) {
// specific initializations for FFNET
}
public override void GrabStoryVariables() { // special implementation for FFNET here }
public override void GenerateStoryInfo() { // special implementation for FFNET here }
}
I know OOP is hard to grasp when you don't have much experience in it. So feel free to ask questions.
If you do it right, then you would never need to cast into subclasses.
To answer the question in the comment:
You could make a class variable in the form1.cs file:
private FanBook currentBook;
private void CreateBook()
{
currentBook = new FFNETFanBook("http://...");
}
private void AnotherMethod() {
if ( currentBook != null ) {
currentBook.GrabStoryVariables();
} else {
throw new Exception("Book not initialized yet.");
}
}
Implement an interface named IAuthors and define the Method you want
Interface IAuthors
{
//method
void authorMethod();
}
Implement the interfaces across your classes
Public Class FanFictionAuthors:IAuthors
{
public void authorMethod()
{
//fanfiction specific action
}
}
Public class SciFiAuthors:IAuthors
{
public void authorMethod()
{
//scifiauthor specific action
}
}
Now make the following changes in your existing code
private void btnGetInfo(object sender, EventArgs e)
{
IAuthors auth=CreateBook();//Use a Interface ref
auth.authorMethod();//Runtime will decide which authorMethod to call depending
//on the object returned.
}
//Note that i am returning the Interface type instead of the void
private IAuthors CreateBook()
{
if (addressBar.Text.Contains("fanficauthors.net"))
{
return new FanFictionAuthors();//Return your object
}elseif(addressBar.Text.Contains("scificauthors.net"))
{
return new SciFiAuthors();//Return your object
}
}
You could create a list in the parent and add childs to that list. Then you can akso walk that list to see if childs are finished and such.
ChildList.Add(new fan....)
I have a C# class that has some functionality that I'd like to allow a client of the class to override. Specifically I'd like the following:
If the client does nothing, they get our default behavior
The client can override the behavior and cause our default behavior to not be called.
The client can override the behavior and cause our default behavior to be called as a pre/post/middle operation.
My current thinking is to:
Expose an event that the client would subscribe to if they wanted to override the behavior.
Expose a method with the default behavior (that matches the signature of the event):
void DefaultBehavior()
Whenever we attempt to fire the event, if the delegate is null, we call our default behavior method, otherwise, we call the delegate of the event:
if (eventDelegate == null)
DefaultBehavior();
else
eventDelegate();
When the client overrides the behavior they can optionally call our DefaultBehavior method to get the desired behavior.
Do you think this approach will be intuitive enough from the client's perspective? Or can you suggest any alternatives that might be better?
Well, if you want your client to override some behavior, why not create a virtual function, an let the client actually override it?
It's the straightforward way of accomplishing this. No need to reinvent the wheel.
If I understand your question, by client you mean some code calling your class, and not overriding your class, assuming you need to do it this way (I agree with #zmbq answer if you can do it that way):
You can make your method have 2 overloads, one with no parameters and another receiving a Action object
public void methodName()
public void methodName(Action delegate)
then in the body of methodName() you will call the other method with defaultAction
public void methodName()
{
methodName(DefaultBehavior);
}
finally in the second method you just call the delegate passed as parameter, without caring if it's the default or not
public void methodName(Action delegate)
{
delegate();
}
the client of your class will see this two overloads and decide wether to use the default or give a custom behavior
EDIT:
Ok, last try :), according to your last comment would it work for you to have an instance field
private Action behaviorDelegate = DefaultBehavior;
Anywhere in your class you can assign to behaviorDelegate a different behavior, and then you don't need an if statement since the behavior will always be in delegate variable whether it is the default or not. It is not a big change but it seems cleaner to me.
You could (perhaps?) also do it without events:
Declaration:
public class DemoClass
{
public delegate string MyDelegate(string testValue);
public static MyDelegate DefaultBehavior
{
get
{
return testValue =>
{
return String.Concat(testValue,
", now with 99% more exclamation points!!!!!!!!");
};
}
}
public MyDelegate ModifyString = testValue =>
{
return DemoClass.DefaultBehavior(testValue);
};
}
Use:
// first, default:
DemoClass demoObject = new DemoClass();
Console.WriteLine(demoObject.ModifyString("My test string"));
// now, pure "override":
demoObject.ModifyString = testVal =>
{ return String.Concat(testVal, ", this time with question marks????");
};
Console.WriteLine(demoObject.ModifyString("Second test string"));
// finally, define a delegate that overrides and calls default:
DemoClass.MyDelegate combined = testVal =>
{ return String.Concat(DemoClass.DefaultBehavior(testVal),
", now we're really tricky");
};
demoObject.ModifyString = combined;
Console.WriteLine(demoObject.ModifyString("Third test string"));
Output:
My test string, now with 99% more exclamation points!!!!!!!!
Second test string, this time with question marks????
Third test string, now with 99% more exclamation points!!!!!!!!, now we're really tricky
Just use a virtual method:
public class BaseClass {
public virtual void Something() {
Console.WriteLine("base functionality");
}
}
public class Sub1 : BaseClass {
public override void Something() {
// do whatever you want here
base.Something(); // don't call it at all if you like
// do whatever you want here
}
}
Is it possible to design a method in such a fashion, that it knows it must automatically call a next method in succession upon exiting?
In the following example, I must call Refresh() to cause my form to repaint after this event takes place. The problem is that, it's ugly to call Refresh() after, for example, 20 different events which must make the form refresh. e.g
private void PriorityLine_Click(object sender, EventArgs e)
{
_showPriorityLine = (_showPriorityLine) ? false : true;
Refresh(); // Must call refresh for changes to take effect.
}
I suppose what I'm looking for is some kind of signature I can apply to the method to cause it to automatically chain to the next method, regardless from where its called. e.g
(I know this isn't syntactically correct.)
private void PriorityLine_Click(object sender, EventArgs e).Refresh()
{
_showPriorityLine = (_showPriorityLine) ? false : true;
}
I want to seperate the interface of the method, from the logic contained within the method. I understand it would be the exact amount of effort, if not more. For example, if I were to edit the method and accidently removed Refresh, it would cause my application to break. Whereas, if the Refresh method was outside of the actual logic of the method, I could do anything within the method without worrying about removing the next chain of logic.
Sounds like what you want is Aspect Oriented Programming, there are a number of different frameworks to enable you to have stuff "magically" happen after some set of methods have run, have a look here AOP programming in .Net?
I'm not aware of any really clean way. One method would be to use PostSharp.
You could encapsulate the changes which would cause the form to refresh into form-level properties.
For instance,
private bool _showPriorityLine;
private bool ShowPriorityLine
{
get { return _showPriorityLine; }
set
{
_showPriorityLine = value;
Refresh();
}
}
Then your event would just be
private void PriorityLine_Click(object sender, EventArgs e)
{
ShowPriorityLine = !ShowPriorityLine;
}
Of course, that only cleans up your code if you have several events manipulating the same variables that cause the form to need refreshing.
Taking into consideration your particular problem and the solutions posted, I would say the "cleanest" approach here would be to implement a Property Changed Notification just for internal use in the form i.e. you don't need to expose the event like in the MSDN example.
This way you could maintain an internal list of properties that you know will require the form to be refreshed e.g.
private List<string> _refreshProps = new List<string>();
private bool _showPriority;
public void Form()
{
_refreshProps.Add("ShowPriority");
... etc
}
// only implement properties like this that need some extra work done
public bool ShowPriority
{
get { return _showPriority; }
set
{
if (_showPriority != value)
{
_showPriority = value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("ShowPriority");
}
}
}
// basic property that doesn't require anything extra
public bool AnotherProperty { get; set; }
public void Refresh()
{
// refresh the form
}
protected void OnPropertyChanged(string name)
{
if (_refreshProps.Contains(name))
Refresh();
}
The benefit of this approach is if in the future you needed to do other "stuff" after particular properties you can simply introduce another list and handle it again in your OnPropertyChanged method.
Don't call Refresh, call Invalidate. The mechanism you need is already built into Windows. Calling Invalidate simply makes a note that the window needs repainting. The operating system will eventually post a WM_PAINT message (typically after the root DispatchMessage call finishes, but the exact implementation is irrelevant).
Use a property that calls Refresh in the setter.
Something like this:
private void RefreshAfter(Action action)
{
action();
Refresh();
}
UPDATED TO MAKE IT MORE OBVIOUS:
private void DoSomeUiShiznit(Action action)
{
action();
// other parts of the code don't realize that Refresh has to be called.
// But that's cool. I got it covered.
Refresh();
}
private void PriorityLine_Click(object sender, EventArgs e)
{
DoSomeUiShiznit(() => { _showPriorityLine = !_showPriorityLine; });
}
UPDATE -- Just a message to the down-voters:
What some of you are too blind to see is that this is not all that different from:
[SomeRefreshAttribute]
private void PriorityLine_Click(object sender, EventArgs e)
{
_showPriorityLine = !_showPriorityLine;
}
Except that it is simpler, and doesn't require adding another framework to the solution. And yet the other answer suggesting as much don't get down-voted!
What's wrong with you people?