A way to store a method in a variable? - c#

Hello I am new to programming.
Basically I need to store a method A from class A in variable A from class B inside a method from class B but I cannot seem to find a way.
To give an example:
Class A
public void methodA()
{
*method*
}
Class B
Delegate variableA; //I believe using Delegate is wrong
public void methodB();
{
variableA = ClassA.methodA();
}
Then in Class B there would be another method that will utilize the variable with the stored method.
public void methodC();
{
variableA;
}
This isn't the exact code I have but this is basically the gist of it. Any help is appreciated :)
Edit: Thanks for the help everyone!

ClassA definition:
public class ClassA
{
public void MethodA()
{
Console.WriteLine("Hello World!");
}
}
ClassB definition:
public class ClassB
{
private Action VariableA { get; set; }
public void MethodB(ClassA classA)
{
VariableA = classA.MethodA;
}
public void MethodC()
{
VariableA();
}
}
Program definition:
static void Main(string[] args)
{
ClassA classA = new ClassA();
ClassB classB = new ClassB();
classB.MethodB(classA);
classB.MethodC();
Console.ReadLine();
}

Here is an example:
public class Test
{
private Action<int> hiddenMethod = new Action<int>((i) =>
{
Console.WriteLine(i);
});
public void PublicMethod(int i)
{
hiddenMethod(i);
}
}
And using it:
class Program
{
static void Main(string[] args)
{
Test t = new Test();
t.PublicMethod(21);
Console.Read();
}
}

Use reflection:
public class A
{
public void MethodA()
{
Console.WriteLine("MethodA");
}
public static void StaticMethodA()
{
Console.WriteLine("StaticMethodA");
}
}
public class B
{
MethodInfo mv = typeof(A).GetMethod("MethodA");
MethodInfo smv = typeof(A).GetMethod("StaticMethodA");
public void CheckA(bool useStatic)
{
if (useStatic) smv.Invoke(null, null);
else mv.Invoke(new A(), null);
}
}
class MainClass
{
[STAThread]
public static void Main(string[] args)
{
var b = new B();
b.CheckA(true);
b.CheckA(false);
}
}
See details in MSDN.

Related

Mark a method for static use

How can I mark a method to use only if the class object was initialized as static?
For example:
public class A
{
public A()
{
}
public void DoIt()
{
{
public void DoItStatic()
{
}
}
public class B
{
private A _aa = new A();
private static A _aaStatic = new A();
public B()
{
}
public void SomeMethod()
{
_aa.DoItStatic(); //Generate Error for that.
_aaStatic.DoItStatic(); //it's fine
{
}
So, if someone tries to use _aa.DoItStatic(), where _aa is not initialized as static, we generate an error.
Is this possible?
Thanks!

Using delegates with non static methods in C#

Asking the same question as
Using delegates with non static methods [no picked answer]
so as to bring a closure to it.
So I use #Adam Marshall's solution, it works, but as soon as I start using it, i.e., Testit():
using System;
public class TestClass
{
private delegate void TestDelegate();
TestDelegate testDelegate;
public TestClass()
{
testDelegate = new TestDelegate(MyMethod);
}
public static void Testit()
{
testDelegate();
}
private virtual void MyMethod()
{
Console.WriteLine("Foobar");
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
TestClass.Testit();
}
}
It started to give the followig Error:
A object reference is required for the non-static field, method, or property
You can test it out here .
How to fix it? (Please fix it if possible instead of directing me to other posts, I've read them but am not able to understand them) Thx.
Either everything has to be static or everything has to be instance. You're getting in trouble because you are mixing and matching.
Everything static:
using System;
public class TestClass
{
private delegate void TestDelegate();
static TestDelegate testDelegate; //<-- static
static TestClass() //<-- static
{
testDelegate = new TestDelegate(MyMethod);
}
public static void Testit()
{
testDelegate();
}
private static void MyMethod()
{
Console.WriteLine("Foobar");
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
TestClass.Testit();
}
}
Everything instanced:
using System;
public class TestClass
{
private delegate void TestDelegate();
TestDelegate testDelegate;
public TestClass()
{
testDelegate = new TestDelegate(MyMethod);
}
public void Testit()
{
testDelegate();
}
private void MyMethod()
{
Console.WriteLine("Foobar");
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
var t = new TestClass();
t.Testit(); //<-- non-static
}
}
Output (same in both examples):
Hello World
Foobar
You could use action C# internal delegate. This way you do not have specify the delegate. Then in your static method you could new up your object.
using System;
public class TestClass
{
Action testDelegate;
public TestClass()
{
testDelegate = new Action(MyMethod);
}
public static void Testit()
{
TestClass ts = new TestClass();
ts.testDelegate();
}
private void MyMethod()
{
Console.WriteLine("Foobar");
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
TestClass.Testit();
}
}
Output:
Hello World
Foobar

Inheriting a generic in c#

I've inherited a large codebase and I'm trying to implement some new functionality into the framework. Basically, in order to do it the "right" way, I would have to modify the entire structure of the framework. since I'm not the guy who designed the framework, nor am I a mind reader, doing so probably isn't going to happen (although I would really love to redesign it all from scratch myself).
So in order to do what I want, I'm trying to implement a decorator pattern, of sorts. This answer from maliger suggests that what I'm doing below is perfectly valid. However, mono doesn't seem to like it; it complains that T cannot be derived from when I declare HappyDecorator
Please forgive the overly simplistic example, but it gets the point across.
public class HappyObject
{
public virtual void print()
{
Console.WriteLine ("I'm happy");
}
}
public class VeryHappyObject : HappyObject
{
public override void print()
{
Console.WriteLine ("I'm very happy");
}
public void LeapForJoy()
{
Console.WriteLine("Leaping For Joy!");
}
}
public class SuperHappyObject : VeryHappyObject
{
public override void print()
{
Console.WriteLine ("I'm super happy!");
}
public void DieOfLaughter()
{
Console.WriteLine("Me Dead!");
}
}
public class HappyDecorator<T> : T where T : HappyObject
{
public string SpecialFactor { get; set; }
public void printMe()
{
Console.WriteLine (SpecialFactor);
print();
}
}
class MainClass
{
public static void Main (string[] args)
{
HappyDecorator<HappyObject> obj = new HappyDecorator<HappyObject> ();
obj.SpecialFactor = Console.ReadLine();
obj.printMe();
}
}
You're typing HappyDecorator to T, but there's no instance of T to use inside that class.
public class HappyDecorator<T> where T : HappyObject
{
private readonly T _instance;
public HappyDecorator(T instance)
{
_instance = instance;
}
public string SpecialFactor { get; set; }
public void printMe()
{
Console.WriteLine(SpecialFactor);
_instance.print();
}
}
Another alternative is to structure it like this with a generic method instead of a generic class. It's not really a decorator then though:
public class HappyDecorator
{
public string SpecialFactor { get; set; }
public void printMe<T>(T instance) where T : HappyObject
{
Console.WriteLine(SpecialFactor);
instance.print();
}
}
And call like:
HappyDecorator obj = new HappyDecorator();
obj.SpecialFactor = Console.ReadLine();
obj.printMe(new HappyObject());
I think this is what you are trying to do:
public interface IhappyObject
{
void Print();
}
public class HappyObject : IhappyObject
{
private IhappyObject obj;
public HappyObject(IhappyObject obj)
{
this.obj = obj;
}
public void Print()
{
obj.Print();
}
}
public class VeryHappyObject : IhappyObject
{
public void Print()
{
Console.WriteLine("I'm very happy");
}
}
public class SuperHappyObject : IhappyObject
{
public void Print()
{
Console.WriteLine("I'm super happy!");
}
}
static void Main(string[] args)
{
HappyObject obj = new HappyObject(new SuperHappyObject());
obj.Print();
}

"An object reference is required for the non-static field, method, or property" - why?

With this code:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("saturnisko: {0}", UkladSloneczny.saturn.mass);
}
}
public class UkladSloneczny
{
private Saturn sat;
public UkladSloneczny(Saturn sat)
{
this.sat = sat;
}
public Saturn saturn
{
get { return this.sat; }
}
}
public class Saturn
{
private int masa;
public Saturn() { masa = 0; }
public int mass
{
get { return this.masa; }
}
}
Why I am getting error like so:
Error 1 An object reference is required for the non-static field, method, or property 'ConsoleApplication1.UkladSloneczny.saturn.get'
?
I assume you're getting it here: Console.WriteLine("saturnisko: {0}", UkladSloneczny.saturn.mass);
UkladSloneczny isn't a static class, so you can't call it like that. You need to either make it static or make a new instance of the class and then call yourClassInstance.saturn.mass.
If the class, method or property are not static then you have to instantiate the object in memory to be able to do anything with it, otherwise the object is null.
So either:
public static class UkladSloneczny
{
private static Saturn sat;
public UkladSloneczny(Saturn sat)
{
sat = sat;
}
public static Saturn saturn
{
get { return sat; }
}
}
OR
new UkladSloneczny().saturn.mass
You need to call it from an instance of UkladSloneczny, like this:
class Program
{
static void Main(string[] args)
{
Saturn saturn = new Saturn();
UkladSloneczny ukladSloneczny = new UkladSloneczny(saturn);
Console.WriteLine("saturnisko: {0}", ukladSloneczny.saturn.mass);
}
}
You need to make an object for UkladSloneczny:
class Program
{
static void Main(string[] args)
{
UkladSloneczny instance = new UkladSloneczny(new Saturn());
Console.WriteLine("saturnisko: {0}", instance.saturn.mass);
}
}
Or you can make the mass of saturn a static property:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("saturnisko: {0}", Saturn.mass);
}
}
public class Saturn
{
private static int masa = 0;
public Saturn() { }
public static int mass
{
get { return masa; }
}
}

Passing Delegate Methods Across Classes/Files

I have a method in a class in another file that I want to take a dynamic method. I'm having some difficulty negotiating the setup. Any help would be appreciated, thanks!
for example...
File #1:
class DoSomethingClass
{
// define delegate
public delegate void DelegateMethod();
public void Main()
{
DelegateMethod d = Func1;
AnotherClass.CallsDynamicMethod("Test1", d);
d = Func2;
AnotherClass.CallsDynamicMethod("Test2", d);
// will this work?
// AnotherClass.CallsDynamicMethod("Test3", DoSomethingClass.instance.Func3);
}
// candidate methods for delegation
void Func1()
{ Console.WriteLine("calling Func1"); }
void Func2()
{ Console.WriteLine("calling Func2"); }
public void Func3()
{ Console.WriteLine("calling Func3"); }
}
File #2:
class AnotherClass
{
public static void CallsDynamicMethod(string words, DelegateMethod dynamicMethod)
{
Console.WriteLine("this is a " + words + " to call...");
dynamicMethod();
}
}
Hope this answers your problem
class Program
{
static void Method()
{
Console.WriteLine("Method");
}
static void Main(string[] args)
{
Action a = Method;
MyClass.SomeMethod(a);
MyClass.SomeMethod(Method);
Console.ReadLine();
}
}
class MyClass
{
public static void SomeMethod(Action del)
{
del();
}
}

Categories