I am trying to create an event inside my class and handle it from static void main method.my event is triggered by a method named checkAge().But i have got an error like this :
Error1-An object reference is required for the non-static field,
method, or property 'Event.Program.m_AgeChecker(int)
I think i did all prats that i had to do,& i don't know what is the problem.
Code of my first class
class Mahmud
{
public Mahmud()
{
name = "mahmud";
age = 25;
}
private string name;
private int age;
public string Name
{
get{return name;}
set{name=value;}
}
public int Age
{
get { return age; }
set { age = value; }
}
public void checkAge()
{
AgeUpdate(age);
}
public delegate void AgeEventHandler(int mAge);
public event AgeEventHandler AgeUpdate;
}
Code of the second class
static void Main(string[] args)
{
Mahmud m = new Mahmud();
m.AgeUpdate += new Event.Mahmud.AgeEventHandler(m_AgeChecker(m.Age));
m.Age = 16;
m.checkAge();
m.Age = 27;
m.checkAge();
}
private void m_AgeChecker(int A)
{
if (A > 25)
{
Console.WriteLine("!");
}
else
{
Console.WriteLine("ok");
}
}
It looks like you are calling a non-static method from a static method. You will need to make the method static.
static void m_AgeChecker(int A)
{
if (A > 25)
{
Console.WriteLine("!");
}
else
{
Console.WriteLine("ok");
}
}
Related
I have a class where I implement a timer. I want to make xUnit tests for that class. When i try to run the tests i have the following error
System.NullReferenceException : Object reference not set to an instance of an object.
What i am doing in the constructor shouldn't fixed the specific error? Why not? Can someone explain to me why I got that error?
GuessingGameTimerTests.cs
private readonly GuessingGameTimer t;
public GuessingGameTimerTests(GuessingGameTimer t)
{
this.t = t;
}
[Fact]
public void StartTimerTest()
{
t.SetTimer(30000);
bool expected = t.IsEnabled();
Assert.True(expected);
}
....
GuessingGameTimer.cs
public class GuessingGameTimer
{
public event EventHandler OnNumberChanged;
private System.Timers.Timer NumberGeneratorTimer;
private int replacetime; // Time in seconds
private int reSetValue; // Time in seconds
//constractor starts the timer
public GuessingGameTimer(int replacetime)
{
this.replacetime = replacetime;
reSetValue = replacetime;
SetTimer(replacetime);
}
public void SetTimer(int replacetime)
{
NumberGeneratorTimer = new System.Timers.Timer(replacetime);
NumberGeneratorTimer.Elapsed += OnTick;
NumberGeneratorTimer.AutoReset = true;
NumberGeneratorTimer.Enabled = true;
this.replacetime = getSeconds();
reSetValue = getSeconds();
}
public void ResetTimer()
{
NumberGeneratorTimer.AutoReset = true;
NumberGeneratorTimer.Enabled = true;
replacetime = reSetValue;
}
public void StopTimer()
{
NumberGeneratorTimer.Enabled = false;
}
public int getSeconds()
{
return replacetime;
}
public Boolean IsEnabled()
{
return NumberGeneratorTimer.Enabled;
}
public GuessingGameTimerTests()
{
this.t = new GuessingGameTimer(3000);
}
Basically I want to launch an event when a string reaches a specific length.
I have a Static String
Static String _Info;
So i have My Delegate that has an integer as a Parameter !
public Delegate void ReachLengthHandler(int Length);
and My event :
public event ReachLengthHandler ReachLengthEvent;
And a Method that Keep addingSome informations to that string :
public void AddInfo()
{
new Thread(() =>
{
while(true)
_Info += ""; //Basically add the inputs of the user here !
if (_Info.Length > 500)
{
if (ReachLengthEvent != null)
ReachLengthEvent(_Info.Length);
}
}).Start();
}
Do you think its the right way to do this event or there are any cleaner ways ?
EDIT :
I want this event because I want to save this string in a Database table row so I don't want to expand the possible size of a row !
As some pointed out in the comments, you may be trying to solve an instance of the XY Problem -- but assuming you're not, you are not approaching things in an object-oriented way, starting with encapsulation.
This could be a start, FWIW:
public class MaxLengthEventArgs : EventArgs
{
public MaxLengthEventArgs(string value)
{
LastAppended = value;
}
public string LastAppended { get; private set; }
}
public delegate void MaxLengthEventHandler(object sender, MaxLengthEventArgs args);
public class StringAccumulator
{
protected StringBuilder Builder { get; private set; }
public StringAccumulator(int maxLength)
{
if (maxLength < 0)
{
throw new ArgumentOutOfRangeException("maxLength", "must be positive");
}
Builder = new StringBuilder();
MaxLength = maxLength;
}
public StringAccumulator Append(string value)
{
if (!string.IsNullOrEmpty(value))
{
var sofar = value.Length + Builder.Length;
if (sofar <= MaxLength)
{
Builder.Append(value);
if ((OnMaxLength != null) && (sofar == MaxLength))
{
OnMaxLength(this, new MaxLengthEventArgs(value));
}
}
else
{
throw new InvalidOperationException("overflow");
}
}
return this;
}
public override string ToString()
{
return Builder.ToString();
}
public int MaxLength { get; private set; }
public event MaxLengthEventHandler OnMaxLength;
}
class Program
{
static void Test(object sender, MaxLengthEventArgs args)
{
var acc = (StringAccumulator)sender;
Console.WriteLine(#"max length ({0}) reached with ""{1}"" : ""{2}""", acc.MaxLength, args.LastAppended, acc.ToString());
}
public static void Main(string[] args)
{
var acc = new StringAccumulator(10);
try
{
acc.OnMaxLength += Test;
acc.Append("abc");
acc.Append("def");
acc.Append("ghij");
Console.WriteLine();
acc.Append("ouch...");
Console.WriteLine("(I won't show)");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.ReadKey();
}
}
Also, keep in mind that strings in .NET are immutable.
Accumulating them using string concatenation, as you did in
_Info += ""
... isn't going to scale well (performance-wise).
'HTH,
Usually eventhandler is used with specific signature.
public delegate void ReachLengthHandler(object sender, EventArgs args);
class Program
{
public event ReachLengthHandler handler;
private const int Threshhold = 500;
public string Info
{
set
{
if (value.Length > Threshhold)
{
this.OnReachLength(null);
}
}
}
public void OnReachLength(EventArgs args)
{
this.handler?.Invoke(this, args);
}
}
I have a form that has a button to get a method executed in another class.
Code on the form:
public delegate void CustomPreviewCreate();
public static event CustomPreviewCreate CustomPreviewCreate_Do;
private void CreatePreview()
{
if (CustomPreviewCreate_Do !=null)
{
CustomPreviewCreate_Do();
}
}
This event then gets handled in another class. What I would like to achieve is that I can feed back to the form some form of return value if the method correctly executed.
What I tried so far does not get me the result.
Here is the code:
public void Initialize()
{
SubAsstViewPartControl.CustomPreviewCreate_Do += SubAsstViewPartControl_CustomPreviewCreate_Do;
// this gives me a the compiler error that the return type is wrong
}
private bool SubAsstViewPartControl_CustomPreviewCreate_Do()
{
// do stuff
return false;
}
Is there any direct way to return value from an event handler or I need to use a separate static field to store the event result in?
Update:
Per #Jon's comment, which seemed the simplest to me, I added an answer below demonstrating the simplest approach.
The common approach is to encapsulate your value in the type of EventArgs your event expects. For example, the Framework's CancelEventArgs contains a settable bool Cancel property, allowing each CancelEventHandler to assign a value. The sender can then read the property after the event has been invoked. You could also use a container-like EventArgs class if you want to collect separate values from individual event handlers. For example:
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
public class SingleValueEventArgs : EventArgs
{
public int Value { get; set; }
}
public class MultiValueEventArgs : EventArgs
{
private List<int> _values = new List<int>(); // Private to prevent handlers from messing with each others' values
public IEnumerable<int> Values
{
get { return _values; }
}
public void AddValue(int value) { _values.Add(value); }
}
public class Exposer
{
public event EventHandler<SingleValueEventArgs> WantSingleValue;
public event EventHandler<MultiValueEventArgs> WantMultipleValues;
public void Run()
{
if (WantSingleValue != null)
{
var args = new SingleValueEventArgs();
WantSingleValue(this, args);
Console.WriteLine("Last handler produced " + args.Value.ToString());
}
if (WantMultipleValues != null)
{
var args = new MultiValueEventArgs();
WantMultipleValues(this, args);
foreach (var value in args.Values)
{
Console.WriteLine("A handler produced " + value.ToString());
}
}
}
}
public class Handler
{
private int _value;
public Handler(Exposer exposer, int value)
{
_value = value;
exposer.WantSingleValue += exposer_WantSingleValue;
exposer.WantMultipleValues += exposer_WantMultipleValues;
}
void exposer_WantSingleValue(object sender, SingleValueEventArgs e)
{
Console.WriteLine("Handler assigning " + _value.ToString());
e.Value = _value;
}
void exposer_WantMultipleValues(object sender, MultiValueEventArgs e)
{
Console.WriteLine("Handler adding " + _value.ToString());
e.AddValue(_value);
}
}
class Program
{
static void Main(string[] args)
{
var exposer = new Exposer();
for (var i = 0; i < 5; i++)
{
new Handler(exposer, i);
}
exposer.Run();
}
}
}
Per Jon Skeet's comment, which seemed the simplest to me, the simplest approach seems to be as follows:
public delegate bool CustomPreviewCreate(); // here we declare a return type
public static event CustomPreviewCreate CustomPreviewCreate_Do;
private void CreatePreview()
{
if (CustomPreviewCreate_Do !=null)
{
bool returnval = CustomPreviewCreate_Do();
}
}
And then:
// the method is declared to return the same type
bool SubAsstViewPartControl_CustomPreviewCreate_Do()
{
// do stuff
return true; // return the value of the type declared
}
There a class and a delegate C#
public delegate void Super();
public class Event
{
public event Super activate ;
public void act()
{
if (activate != null) activate();
}
}
and C++/Cli
public delegate void Super();
public ref class Event
{
public:
event Super ^activate;
void act()
{
activate();
}
};
in C# I create multicast delegate in the class like this(methods Setplus and setminus)
public class ContainerEvents
{
private Event obj;
public ContainerEvents()
{
obj = new Event();
}
public Super Setplus
{
set { obj.activate += value; }
}
public Super Setminus
{
set { obj.activate -= value; }
}
public void Run()
{
obj.act();
}
}
but in C++/Cli I've got an error - usage requires Event::activate to be a data member
public ref class ContainerEvents
{
Event ^obj;
public:
ContainerEvents()
{
obj = gcnew Event();
}
property Super^ Setplus
{
void set(Super^ value)
{
obj->activate = static_cast<Super^>(Delegate::Combine(obj->activate,value));
}
}
property Super^ SetMinus
{
void set(Super^ value)
{
obj->activate = static_cast<Super^>(Delegate::Remove(obj->activate,value));
}
}
void Run()
{
obj->act();
}
};
Where is the problem?
See: http://msdn.microsoft.com/en-us/library/ms235237(v=vs.80).aspx
C++/CLI follows the same analog as C#. It would be illegal to define this in C#:
public Super Setplus
{
set { obj.activate = Delegate.Combine(obj.activate, value); }
}
It is the same for C++/CLI. Use the +=/-= notation that is defined in the modern syntax.
property Super^ Setplus
{
void set(Super^ value)
{
obj->activate += value;
}
}
actually i refactor some portion of code.
what i want to do is to initialize an object "Task" with an object "TaskArgument".
let s say "TaskArgument" is abstract and "Task" implements a method "OnEnterTask(TaskArgument args)" and is sealed (for some special behavior of the existing system, which is out of scope).
old code:
public sealed class Task : SomeSystemBaseTask {
private int accessMe;
private int meToo;
public void OnEnterTask(TaskArgument args) {
if (args is SimpleTaskArgument) {
accessMe = ((SimpleTaskArgument)args).uGotIt;
meeToo = 0;
} else if (args is ComplexTaskArgument) {
accessMe = ((ComplexTaskArgument)args).uGotItValue * ((ComplexTaskArgument)args).multiplier;
meToo = ((ComplexTaskArgument)args).multiplier - 1;
}
}
}
what would be the best practise avoid the typecheck?
my first stupud thought was:
public abstract class TaskArgument {
internal public abstract Initialize(Task args);
}
public class SimpleTaskArgument : TaskArgument {
public int uGotIt = 10;
internal public Initialize(Task task){
task.accessMe = uGotIt;
}
}
public class ComplexTaskArgument : TaskArgument {
public int uGotItValue = 10;
public int multiplier = 10;
internal public Initialize(Task task){
task.accessMe = uGotItValue*multiplier;
task.meToo = multiplier - 1;
}
}
public sealed class Task : SomeSystemBaseTask {
public int accessMe;
public int meToo;
public void OnEnterTask(TaskArgument args){
args.Initialize(this);
}
}
but then my "accessMe" is public and the "Initialize" method works only with "Task".
so i moved the typechecking to another place (in future).
is there any best practise or good design idea.
..."internal public"... mmhhmm?
another crazy idea was an inner class, but i dont like those and it make such a simple case more complex or don't:
public abstract class TaskArgument {
internal public abstract Initialize(ITaskWrapper wrapper);
}
public class SimpleTaskArgument : TaskArgument {
...
}
public class ComplexTaskArgument : TaskArgument {
...
}
public interface ITaskWrapper {
public int AccessIt { set; get; }
...
}
public sealed class Task : SomeSystemBaseTask {
private int accessMe;
...
class TaskWrapper : ITaskWrapper {
...
}
public void OnEnterTask(TaskArgument args){
args.Initialize(new TaskWrapper(this));
}
}
where is the best place for initialization when it is based on the given Type of the "TaskArgument"?
kindly excuse my bad english knowledge
greetings
mo
Use an interface.
public void OnEnterTask(TaskArgument args) {
if (args is SimpleTaskArgument) {
accessMe = ((SimpleTaskArgument)args).uGotIt;
} else if (args is ComplexTaskArgument) {
accessMe = ((ComplexTaskArgument)args).uGotItValue * ((ComplexTaskArgument)args).multiplier;
}
}
becomes
public void OnEnterTask(ITaskArgument args) {
accessMe = args.GetAccessMe();
}
Then you have your classes implement ITaskArgument and implement the method for each class. In general, when you're doing something like this:
accessMe = ((ComplexTaskArgument)args).uGotItValue * ((ComplexTaskArgument)args).multiplier;
where you're accessing multiple properties on an object to perform a calculation, it usually makes sense to push that logic into the class itself.
Sounds like you want to put the logic associated with each sub-class of TaskArgument onto that class. You could add an abstract method to TaskArgument called Calculate that has the sub-class specific calculation. That would remove the need for your if statements completely:
public class Task {
private int accessMe;
public void OnEnterTask(TaskArgument args)
{
accessMe = args.Calculate();
}
}
You would then put the multiplication or whatever is appropriate into each sub-class.
I would create a public interface, which only exposes the Intialize method. Do your calculations in your derived classes e.g.
public interface ITaskArgument
{
void Initialize(Task task);
}
public abstract class TaskArgument : ITaskArgument
{
protected int _value;
public class TaskArgument(int value)
{
_value = value;
}
public abstract void Initialize(Task task);
}
public class SimpleTaskArgument : TaskArgument, ITaskArgument
{
public SimpleTaskArgument(int value)
: base (value)
{
}
public override void Initialize(Task task)
{
task.AccessMe = _value;
}
}
public class ComplexTaskArgument : TaskArgument, ITaskArgument
{
private int _multiplier;
public ComplexTaskArgument(int value, int multiplier)
: base (value)
{
_multiplier = multiplier;
}
public override void Initialize(Task task)
{
task.AccessMe = _value * _multiplier;
}
}
public class Task
{
public Task()
{
}
public int AccessMe { get; set; }
public void OnEnterTask(ITaskArgument args)
{
args.Initialize(this);
}
}
example
SimpleTaskArgument simpleArgs = new SimpleTaskArgument(10);
ComplexTaskArgument complexArgs = new ComplexTaskArgument(10, 3);
Task task = new Task();
task.OnEnterTask(simpleArgs);
Console.WriteLine(task.AccessMe); // would display 10
task.OnEnterTask(complexArgs);
Console.WriteLine(task.AccessMe); // would display 30
OK, changed my answer a bit in light of the changing requirements appearing in the comments! (Sheesh, scope creep or what?!)
public class Task
{
public int Variable1 { get; internal set; }
public int Variable2 { get; internal set; }
public void OnEnterTask(ITaskInitializer initializer)
{
initializer.Initialize(this);
}
}
public interface ITaskInitializer
{
void Initialize(Task task);
}
public class SimpleTaskInitializer : ITaskInitializer
{
private int uGotIt = 10;
public void Initialize(Task task)
{
task.Variable1 = uGotIt;
}
}
public class ComplexTaskInitializer : ITaskInitializer
{
private int uGotIt = 10;
private int multiplier = 10;
public void Initialize(Task task)
{
task.Variable1 = uGotIt;
task.Variable2 = uGotIt * multiplier;
// etc - initialize task however required.
}
}
You could create overloads of Task as one option:
public class SimpleTask : Task
{
public override void EnterTask(TaskArgument arg)
{
var s = (SimpleTaskArgument)arg;
}
}
So each task type deals with an equivalent argument type. Or, you can move the logic to a TaskFactory with a static method that returns an int, and has the type checking argument there.
public static class TaskFactory
{
public static int GetVal(TaskArgument arg)
{
if (args is SimpleTaskArgument) {
return ((SimpleTaskArgument)args).uGotIt;
} else if (args is ComplexTaskArgument) {
return ((ComplexTaskArgument)args).uGotItValue * ((ComplexTaskArgument)args).multiplier;
}
}
}
Your interface implementation also would work; I wouldn't discount that... or define an abstract method within Taskargument, that each overrides to return the value.
HTH.