prevent method execution on design time using attributes - c#

Is there a way to prevent a method from execution if it is in design time or the method can only be executed at runtime.
I got this problem while creating a custom control because there is a method call in the constructor that will only work at runtime.
now at design time while designing the form and use that control, then the form will generate the error.
now i tried this at the constructor of the user control
public ctrl_information()
{
InitializeComponent();
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)) return;
SomeMethod();
//Other code
}
what i want to achieve now is something like this.
[ExecuteOnlyAtRuntime]
public void SomeMethod()
{
//Code here
}
Then call it like this.
public ctrl_information()
{
InitializeComponent();
//if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)) return; -- removing this line
SomeMethod();
}
Is it possible?
Please shed some light on this.
Thank you

Assuming that someMethod is in a control, you may use Component.DesignMode.
So a simple approach could be
public void SomeMethod()
{
if (this.DesignMode == false)
{
//Code here
}
}
Incase the Some function is not in a control, you may implement something like this -
public void SomeFunciton()
{
if(VisualStudioUtility.IsRunningInVisualStudio == false)
{
}
}
static class VisualStudioUtility
{
private const string IDE_EXE = "devenv.exe";
public static bool IsRunningInVisualStudio
{
get
{
return Environment.CommandLine.Contains(IDE_EXE);
}
}
}

Related

How do I avoid repetitive if statements without interrupting event to run other actions?

There are two classes that interact in this problem. I'd like to note I'm using Unity:
TaskHandler
public class TaskHandler{
public event Action<GameObject> TaskResponses;
private void Update(){
if (someCondition){
TaskResponses?.Invoke(taskObj);
}
}
}
TaskBase
public class TaskBase: MonoBehaviour{
private TaskHandler taskHandler;
private void Start(){
taskHandler = gameObject.GetComponent<TaskHandler>();
taskHandler.TaskResponses += TaskResponse;
}
private void TaskResponse(GameObject taskObj){
//if check so that only specific TaskResponses run.
if (taskObj == gameObject){
//functions
}
}
}
The problem I'm facing is with methods that extend TaskResponse().
public class SpecificTask{
public override void TaskResponse(GameObject taskObj)
{
base.TaskResponse(taskObj);
//another if check
if (taskObj == thisTaskObj){
//some other functionality
}
}
}
I don't want to do another if check. I tried the following:
public class TaskBase: MonoBehaviour{
//Start() method omitted
private void TaskResponse(GameObject taskObj){
//if check so that only specific TaskResponses run.
if (taskObj == gameObject){
//functions
}
else{
//Effectively stops code from SpecificTask to continue running,
//But other Actions are no longer called.
return;
}
}
}
But the return statement stops TaskReponses() from other classes to run. By that, I mean that if I had Class Task1 and Task2, and Task1's TaskResponse() runs first, but it runs the else statement, it stops and does not run Task2's TaskResponse().
How can I improve my code to stop writing repetitive if checks, while have my code check all Action like I want it to? Should I not be using event for this scenario at all?
Thank you!
You could make it not void but rather bool which indicates if the method was successfully terminated or aborted like e.g.
public class TaskBase
{
public virtual bool TaskResponse(GameObject taskObj)
{
if(taskObj != thisObj) return false;
// Default stuff to happen
return true;
}
}
Then you can do
public class MyTask
{
public override bool TaskResponse (GameObject taskObj)
{
if(!base.TaskResponse(taskObj)) return false;
// Default stuff already happened
// Now you can add additional stuff here
return true;
}
}
Alternatively if you want to avoid that if check entirely what I also do often is using separate methods like
public class TaskBase
{
public void TaskResponse (GameObject taskObj)
{
if(taskObj != thisObj) return;
TaskResponseInternal();
}
protected virtual void TaskResponseInternal()
{
// Default stuff to happen
}
}
And then simply override that instead
public class MyTask
{
protected override void TaskResponseInternal ()
{
// If you want also the default stuff
base.TaskResponseInternal();
// Additional stuff to happen
}
}

Determine form's identity (type information) at runtime

Say I have a common class that performs some time-consuming step (eg. saving stuff to USB). I'd like to be able to call that code from multiple forms and receive feedback whenever a step is completed. How does the common class know to whom to send feedback to? The code below describes the situation:
// ### Common class frmCommon ###
// Parent form (when feedback on some slow operation is required)
private static Form m_frmParent = null;
// ...
public static void SetParentForm(Form frmParent)
{
// When some time consuming process takes place (such as saving to USB), setting the
// parent form allows feedback to be given to the user (eg. as a progress bar)
m_frmParent = frmParent;
}
public static void DoSomething()
{
for (int nStep = 0; nStep < 100; nStep++)
{
// Tell the parent form how many product sets (groups of 20) there are to read
if (m_frmParent != null)
{
// How to decide whether to call form 1 or form 2?
((frmForm1)m_frmParent).SendFeedback(nStep);
((frmForm2)m_frmParent).SendFeedback(nStep);
}
// Perform the time-consuming step...
SlowStep(nStep);
}
}
// ### FORM 1 frmForm1 ###
private void SomeEventForm1(int nStep)
{
frmCommon.SetParentForm(this);
frmCommon.DoSomething();
frmCommon.SetParentForm(null);
}
public void SendFeedback(int nStep)
{
// Do something like update a progress bar on form 1
Application.DoEvents();
}
// ### FORM 2 frmForm2 ###
private void SomeEventForm2(int nStep)
{
frmCommon.SetParentForm(this);
frmCommon.DoSomething();
frmCommon.SetParentForm(null);
}
public void SendFeedback(int nStep)
{
// Do something like update a progress bar on form 2
Application.DoEvents();
}
Aiming for .NET 2.0 if that makes a difference.
I'd rather use an event:
public class SlowProcess {
...
// Simplest, not thread safe
public static event EventHandler<int> StepChanged;
public static void DoSomething() {
for (int nStep = 0; nStep < 100; nStep++) {
if (null != StepChanged)
StepChanged(null, nStep);
SlowStep(nStep);
}
}
}
...
public partial class MyEventForm: Form {
...
private void onStepChange(Object sender, int nStep) {
//TODO: update form here after receiving a feedback
}
private void TraceSlowProcess() {
// feedback is required
SlowProcess.StepChanged += onStepChange;
try {
SlowProcess.DoSomething();
}
finally {
// No need of feedback
SlowProcess.StepChanged -= onStepChange;
}
}
}
The calling code will have to provide a delegate to that class. When the class is done with the time consuming process, it will call that delegate to inform the calling code that it finished. Look here for a good tutorial on how to do this.
1 - If SendFeedback is a function you implemented in both forms, and they do the same, consider creating a single static method in a static class to extend the Form:
public static class FormExtender
{
public static void SendFeedback(this Form frm, int nStep)
{
//do what must be done
//you can call this anyhere using, for instance: m_frmParent.SendFeedback(nStep)
//when you call it like that, m_frmParent will be given to this function as the argument frm
}
}
2 - But if the methods are different in both forms, I suggest you create an interface:
interface IFormWithFeedback
{
void SendFeedback(int nStep);
}
Then form1 and form2 should implement this (just add , IFormWithFeedBack where your forms are declared):
public class frmForm1 : Form, IFormWithFeedback
public class frmForm2 : Form, IFormWithFeedback
And your parent form inside that class should be an IFormWithFeedback instead of a form:
private static IFormWithFeedback m_frmParent = null;
Both options (extension method or interface) would allow you to call SendFeedback direclty from m_frmParent without casting it.

C# how to implement "singleton" method

We all know about the singleton pattern.
How do you implement a singleton "method"? - a method that is called only once and any other call will do nothing.
I can think a few ways (including Lazy - if (!.IsValueCreated) {... value.method();}) but how would you implement it?
I don't think so there is something like a singleton method.
If you want your method to do execute the block of code only once then you can do that. This can be done in several ways, one of them could be as follows-
public class Foo
{
private static bool _isInitialied;
public void Initialize()
{
if(_isInitialied)
return;
//TODO: Initialization stups.
_isInitialied = true;
}
}
You could achieve this using actions:
public class Test
{
private Action _action;
private void DoSomething()
{
// Do something interesting
_action = DoNothing;
}
private void DoNothing()
{
}
public Test()
{
_action = DoSomething;
}
public void Call()
{
_action();
}
} // eo class Test

Generics and events

I am making a game and I'm trying to create an way for objects to handle collisions with each other. I want to do something like:
//Imaginary C#
public SomethingThatCollides()
{
CollisionEvent<ObjectA> += CollisionWithObjA;
CollisionEvent<ObjectB> += CollisionWithObjB;
}
void CollisionWithObjA(ObjectA other)
{
//Do something
}
void CollisionWithObjB(ObjectB other)
{
//Do something else
}
When, say, CollisionEvent<ObjectA> is raised (perhaps by some collision checking code), CollisionWithObjA should get called. Same for CollisionWithObjB; when a collision with ObjectB is detected, it will raise the CollisionEvent<ObjectB> event which results in CollisionWithObjB getting called.
Is something like this possible?
Here is the thing, if class is generic and it has static field, it can work like a dictionary with key being type
public class Something {
public class EventsHolder<T>
{
static event Action<T> CollideEvent;
}
public void AddEvent<T>(Action<T> collisionEvent)
{
EventsHolder<T>.CollideEvent = collisionEvent;
}
public void RaiseCollision<T>(T Obj)
{
var Event = EventsHolder<T>.CollideEvent;
if (Event != null) Event(Obj);
}
}
Downside is that it uses static fields which can be inapropriate.
In this case you can use code #Daniel posted.
You can't really create a generic event like that. I suggest you create a special event arguments class that also encapsulates the collided object and check for its type in the event handler method:
public class CollisionEventArgs : EventArgs {
public object Object {
get; private set;
}
// ...
}
You'll need a special dispatcher method to use it:
class SomethingThatCollides {
public SomethingThatCollides(CollisionManager cm) {
cm.CollisionEvent += CollisionWithObj;
}
void CollisionWithObj(object sender, CollisionEventArgs args) {
if (args.Object is ObjectA) {
CollisionWithObjA((ObjectA)args.Object);
}
else if (args.Object is ObjectB) {
CollisionWithObjB((ObjectB)args.Object);
}
}
// ...
}
Or, you can try to solve this with double-dispatching, without using C# events. Look at wikipedia for a collision example.
That's uggly, but...You could have a dicionary of events by type:
Dictionary<Type, object> MyEventsByType;
event Action<A> CollisionEventA;
event Action<B> CollisionEventB;
event Action<C> COllisionEventC;
void Initialize()
{
MyEventsByType = new Dictionary<Type, object>();
MyEventsByType.Add(typeof(A), CollisionEventA);
MyEventsByType.Add(typeof(B), CollisionEventB);
MyEventsByType.Add(typeof(C), CollisionEventC);
}
void RaiseCollision<T>(T Obj)
{
Action<T> Event = (Action<T>)MyEventsByType[typeof(T)];
if (Event != null) Event(Obj);
}

How to execute a method Once during Runtime on c#

Is there a possibility to prevent method execution more than once during Run-time of an Instance without using an external Attribute ?
I hope i was clear !
Bests
Try using a static constructor
public class TestClass
{
static private bool _isExecutedFirst = false;
public void MethodABC()
{
if(!_isExecutedFirst)
_isExecutedFirst = true;
else
throw Exception("Method executed before");
/////your code
}
}
Hope this help
sure, with a flag to indicate whether a method on an instance has been run.
public class RunOnceMethod
{
private bool haveIRunMyMethod = false
public void ICanOnlyRunOnce()
{
if(haveIRunMyMethod)
throw new InvalidOperationException("ICanOnlyRunOnce can only run once");
// do something interesting
this.haveIRunMyMethod = true;
}
}
Yes,
you can use like this
void method(args)
{
static int a;
if(a != 0)
{
return;
}
// body of method and
a++;
}
reason being this static a will not be copied to activation records of the function calls and all will share only one a.
I hope this resolve your question.
No, there is no way to prevent method execution without storing some kind of 'state' saying the method has already been executed.
One way of doing this is a "guard" / check at start:
private bool AExecuted = false;
public void A()
{
if (AExecuted)
return;
else
AExecuted = true;
/* Your code */
}

Categories