How do I pass the parameters from main method to another class?
I have done like this. Is this right approach?
namespace classA
{
class Program
{
public static void Main(string[] args)
{
string abc= new string {"HELLO"};
Console.WriteLine("My result: {0}", ClassB(abc));
Console.Read();
}
public static string ClassB(string abc)
{
//code
return xyz;
}
}
}
well in the code you posted you have only one class with two methods but in principle yes, this would be one way:
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string abc = "HELLO";
Console.WriteLine("My result: {0}", ClassB(abc));
Console.Read();
}
public static string ClassB(string abc)
{
return abc;
}
}
}
My result: HELLO
If you have your second method really in another STATIC class:
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string abc = "HELLO";
Console.WriteLine("My result: {0}", myfuncclass.ClassB(abc));
Console.Read();
}
}
static class myfuncclass
{
public static string ClassB(string abc)
{
return abc;
}
}
}
My result: HELLO
And if your second method is NOT in a static class and your method is NOT static you have to create an instance of the class first and then call your method on this object:
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string abc = "HELLO";
myfuncclass test = new myfuncclass();
Console.WriteLine("My result: {0}", test.ClassB(abc));
Console.Read();
}
}
public class myfuncclass
{
public string ClassB(string abc)
{
return abc;
}
}
}
Related
I need to call a static factory method from a generic method.
Some solution suggest using reflection. Is there no other way to do so? Why C# has this constraint?
Here is my minimal example:
using System;
public class MainClass
{
public static void Main(string[] args)
{
A a = Get<A>("apiA");
B b = Get<B>("apiB");
}
public static T Get<T>(string url)
{
string json = "{}"; // answer received from api
return T.Factory(json); // error CS0119: 'T' is a type parameter, which is not valid in the given context
}
}
class A {
// public field
public static A Factory(string json)
{
// need to do more A-specific thing here
return NotUnderMyControl.FromJson<A>(json);
}
}
class B {
// public fields
public static B Factory(string json)
{
// need to do more B-specific thing here
return NotUnderMyControl.FromJson<B>(json);
}
}
static class NotUnderMyControl {
public static T FromJson<T>(string json) where T : new()
{
return new T();
}
}
You may want to make the methods common in the interface and change static methods to instance methods.
public class MainClass
{
public static void Main(string[] args)
{
A a = Get<A>("apiA");
B b = Get<B>("apiB");
}
static class FactoryCache<T> where T : IFactory<T>, new()
{
public static readonly T Instance = new T();
}
public static T Get<T>(string url) where T : IFactory<T>, new()
{
string json = "{}"; // answer received from api
return FactoryCache<T>.Instance.Factory(json);
}
}
public interface IFactory<T>
{
T Factory(string json);
}
class A : IFactory<A>
{
public A Factory(string json)
{
return NotUnderMyControl.FromJson<A>(json);
}
}
class B : IFactory<B>
{
public B Factory(string json) {
return NotUnderMyControl.FromJson<B>(json);
}
}
I would like to dynamically get the value of the attribute on method, which could be anywhere in the calling hierarchy.
Now I have found the solution using StackTrace's FrameCount and GetFrame. But it's not dynamic
Rollback.cs
namespace AnotationTest
{
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
class RollbackAttribute: Attribute
{
public Guid RollbackGuid { get; set; }
public RollbackAttribute()
{
RollbackGuid = Guid.NewGuid();
}
}
}
Program.cs
class Program
{
static void Main(string[] args)
{
Test();
}
[RollbackAttribute]
public static void Test()
{
Test1();
}
public static void Test1()
{
Test2();
}
public static void Test2()
{
Test3();
}
public static void Test3()
{
Test4();
}
public static void Test4()
{
var framecount = new StackTrace().FrameCount;
System.Reflection.MethodBase method = new StackTrace().GetFrame(framecount-2).GetMethod();
RollbackAttribute rollback = (RollbackAttribute)method.GetCustomAttributes(typeof(RollbackAttribute), true)[0];
}
}
I would like to have a solution to get the attribute value from the Test4 method. But without using StackTrace which is used now. Thank you for any help.
What you want to use is CallContext and its Set/GetLogicalData methods that serves the purpose of traversing data from caller to "callee" without the need to use method parameters or attributes.
class Program
{
static void Main(string[] args)
{
CallContext.LogicalSetData("rollbackGuid", Guid.NewGuid());
Test();
Console.ReadKey();
}
public static void Test()
{
Test1();
}
//[RetryOnExceptionAttribute]
public static void Test1()
{
Test2();
}
public static void Test2()
{
Test3();
}
public static void Test3()
{
Console.WriteLine($"Current thread id: {Thread.CurrentThread.ManagedThreadId}");
Task.Run((() => { Test4(); }));
}
public static void Test4()
{
Console.WriteLine($"Current thread id: {Thread.CurrentThread.ManagedThreadId}");
Console.WriteLine($"Rollback guid: {Rollback.CurrentGuid}");
}
}
static class Rollback
{
public static Guid CurrentGuid => (Guid)CallContext.GetData("rollbackGuid");
}
I'm new to C#, I'm in doubt about how to make this work:
namespace Core {
public class A{
private reandonly string _var;
public A(string var){
_var=var
}
public GetValue() => return _var;
}
}
using System;
namespace Core.Resources {
public static class B{
public static void DoSomething(){
Console.Writeline($"{A.GetValue()}");
}
}
}
public class C{
static void Main(string args[]){
A a = new A("name");
a.Resources.B.DoSomething();
}
}
A is in main folder, B is in Main/Resources folder, together they make a classlib, Program.cs is using this lib. Is there a way to make this work?
If you write a.Resources you are basically trying to retrieve the member Resources of the class A, which is obviously not defined. Since B is a static class defined in the Core.Resources namespace, all you have to do is to change your code as follows:
public class C
{
public static void Main(string args[])
{
A a = new A("A");
Core.Resources.B.DoSomething();
}
}
or, alternatively, if you don't want to reference the namespace every time:
using Core.Resources;
public class C
{
public static void Main(string args[])
{
A a = new A("A");
B.DoSomething();
}
}
Note that if yuu explicitly define a public constructor for A that accepts one or more arguments, the default parameterless constructor is no more available... hence you have to pass a string to the A constructor if you don't want to see an error in your console. Alternatively, you have to rewrite your A class so that it implements a default parameterless compiler, for example:
public class A
{
private reandonly String _var;
public A() : this(String.Empty) { }
public A(String var)
{
_var = var;
}
}
EDIT AS PER OP COMMENTS AND QUESTION CHANGES
public class A
{
private reandonly String _var;
public String Var
{
get { return _var; }
}
public A(String var)
{
_var = var;
}
}
public static class B
{
public static void DoSomething(String text)
{
Console.Writeline(text);
}
}
public class C
{
public static void Main(string args[])
{
A a = new A("name");
B.DoSomething(a.Var);
}
}
I am new to c# and fairly new to programming. I need help with a topic which i have been trying to figure out from the past week. I have 3 files:
Control: this is an interface and should contain the list of my
methods
ControlImpl : this the implementaion of the interfaces.
Runtime: contains which the binding code between the main method
and the interface implementaion
Test_main: from where i call the
runtime method 'call'
Problem: there can be any number of instances(for ex: c, c1, c2, etc) in Control file and each instance should be able to call SetTime() and Nop() methods.
I made a list of the methods SetTime() and Nop(). But how can i add the instance to a list so that each instance when called should call its methods?
CONTROL
namespace create_interface
{
interface Control
{
void SetTime(params object[] paramsArr);
void Nop(params object[] paramsArr);
}
public class CM
{
Control c = new ControlImpl();
public List<object> ControlMain()
{
List<object> methods = new List<object>();
methods.Add(new Action<object[]>(c.SetTime));
methods.Add(new Action<object[]>(c.Nop));
return methods;
}
}
}
ControlImpl :
namespace create_interface
{
public class ControlImpl : Control
{
void Control.SetTime(params object[] paramsArr)
{
Console.WriteLine("inside Control.SetTime {0} ", paramsArr[0]);
}
void Control.Nop(params object[] paramsArr)
{
Console.WriteLine("inside Control.Nop ");
}
}
}
Runtime:
namespace create_interface
{
public class runtime
{
public void call(params object[] methodparams)
{
if ((methodparams[0].Equals(0)) || (methodparams[0].Equals(1)))
{
//List<Control> objectlists = cmObject.ControlObjectList();
List<object> methods = cmObject.ControlMain();
//Console.WriteLine(methods.Count);
Action<object[]> method = (Action<object[]>)methods[(int)methodparams[0]]; //object[]
object[] args = new object[] { methodparams[1] };
method(args);
}
else
Console.WriteLine("wrong ID number entered");
}
Test_main:
namespace create_interface
{
class test_main
{
static void Main(string[] args)
{
long time;
CallingFunc CF = new CallingFunc();
Console.WriteLine("enter method ID");
int methodID = Convert.ToInt32(Console.ReadLine());
try
{
switch (methodID)
{
case 0:
Console.WriteLine("enter the time in long");
time = Convert.ToInt64(Console.ReadLine());
CF.call(methodID, time);
break;
case 1:
CF.call(methodID, null);
break;
default:
Console.WriteLine("you entered wrong method ID or parameters");
break;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Please take a look at the following solution and we can use it as a base to come up with your final solution:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace StackOverflow38200633
{
class Program
{
static void Main(string[] args)
{
Collection<IControl> controls = new Collection<IControl>();
controls.Add(ControlFactory.Create());
controls.Add(ControlFactory.Create());
controls.Add(ControlFactory.Create());
ControlManager manager = new ControlManager(controls);
Console.WriteLine("Enter method ID:");
int methodID = Convert.ToInt32(Console.ReadLine());
try
{
switch(methodID)
{
case 0:
Console.WriteLine("Enter the time in long: ");
long time = Convert.ToInt64(Console.ReadLine());
manager.InvokeAllSetTime(time);
break;
case 1:
manager.InvokeAllNop();
break;
default:
Console.WriteLine("You entered wrong method ID or parameters");
break;
}
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
public interface IControl
{
void SetTime(long time);
void Nop();
}
public class ConcreteControl : IControl
{
public void SetTime(long time)
{
Console.WriteLine("inside Control.SetTime {0} ", time);
}
public void Nop()
{
Console.WriteLine("inside Control.Nop ");
}
}
public class ControlManager
{
public void InvokeAllSetTime(long time)
{
foreach(IControl control in _controls) control.SetTime(time);
}
public void InvokeAllNop()
{
foreach(IControl control in _controls) control.Nop();
}
public ControlManager(Collection<IControl> controls)
{
_controls = controls;
}
public Collection<IControl> _controls { get; private set; }
}
public static class ControlFactory
{
public static IControl Create()
{
return new ConcreteControl();
}
}
}
I have a static class with number of different methods.
I have another class, and with each instance of this class, I would like it to have a method which calls one of the methods in the static class. For each instance, I want be able to specify which of the methods it will use via the constructor of this class.
Is there a simple way to do this? Should I be using delegates/interfaces?
Do the methods all have the same signature? If so, a delegate would certainly be a good approach... although it wouldn't restrict the caller to passing in a method group from the static class. If that's not a problem, here's a sample:
using System;
public static class TestMethods
{
public static void Foo(int x)
{
Console.WriteLine("Foo " + x);
}
public static void Bar(int x)
{
Console.WriteLine("Bar " + x);
}
}
public class DummyClass
{
private readonly Action<int> action;
public DummyClass(Action<int> action)
{
this.action = action;
}
public void CallAction(int start, int end)
{
for (int i = start; i < end; i++)
{
action(i);
}
}
}
class Test
{
static void Main()
{
DummyClass d1 = new DummyClass(TestMethods.Foo);
DummyClass d2 = new DummyClass(TestMethods.Bar);
d1.CallAction(2, 4);
d2.CallAction(3, 7);
}
}
Here is what you are looking for:
public delegate void MyStaticMethodInvoker(params object[] values);
public class TestStatic
{
public static void TestMethod1(params object[] values)
{
Console.WriteLine("TestMethod1 invoked");
}
public static void TestMethod2(params object[] values)
{
Console.WriteLine("TestMethod2 invoked");
}
public static void TestMethod3(params object[] values)
{
Console.WriteLine("TestMethod3 invoked");
}
}
public class TestClass
{
private MyStaticMethodInvoker _targetMethod;
public TestClass(MyStaticMethodInvoker targetMethod)
{
_targetMethod = targetMethod;
}
public void CallTargetedStaticMethod()
{
_targetMethod.Invoke(1,2,3,4);
}
}
And then you can create instances of TestClass and in constructor define target static method:
TestClass tc1 = new TestClass(new MyStaticMethodInvoker(TestStatic.TestMethod1));
tc1.CallTargetedStaticMethod();
TestClass tc2 = new TestClass(new MyStaticMethodInvoker(TestStatic.TestMethod2));
tc2.CallTargetedStaticMethod();
TestClass tc3 = new TestClass(new MyStaticMethodInvoker(TestStatic.TestMethod3));
tc3.CallTargetedStaticMethod();