Hi guys i need return value from my action, see this sample..
public class B
{
public void test()
{
Action asd = test2;
}
private void test2()
{
Console.WriteLine("LOL");
}
}
This sample work, but i need to return byte from test2 method like this..
public class B
{
public void test()
{
Action asd = test2;
}
private byte test2()
{
Console.WriteLine("LOL");
return 0;
}
}
Any solution?
thank you it work now, i have edited my code in this..
public class B
{
public void test()
{
Func<byte> asd = test2;
byte x = asd();
Console.WriteLine(x);
}
private byte test2()
{
Console.WriteLine("LOL");
return 0;
}
}
Related
I need to pass type as an argument to a generic class. I am trying to get the type from list of types. Example:
void Main()
{
var test = new Test();
test.testMethod();
}
public static class ListClass<T>
{
public static bool getValues()
{
return true;
}
}
public class X { public int a; public int b; }
public class Y { public string s; public float f; }
class Test
{
List<Type> listType = new List<Type>();
public Test()
{
listType.Add(typeof(X));
listType.Add(typeof(Y));
}
public void testMethod()
{
Console.WriteLine(ListClass<X>.getValues());
Console.WriteLine(ListClass<Y>.getValues());
}
}
I want to loop the calls instead of calling in each line.
Let's assume, for the sake of the argument, that the code you posted in your question, as per my request in the comments, was this:
void Main()
{
var test = new Test();
test.testMethod();
}
public static class ListClass<T>
{
public static bool getValues()
{
return true;
}
}
public class X { public int a; public int b; }
public class Y { public string s; public float f; }
class Test
{
List<Type> listType = new List<Type>();
public Test()
{
listType.Add(typeof(X));
listType.Add(typeof(Y));
}
public void testMethod()
{
Console.WriteLine(ListClass<X>.getValues());
Console.WriteLine(ListClass<Y>.getValues());
}
}
That's basically code that will compile and will run. So now you want to know how to actually run this illegal code:
public void testMethod()
{
foreach (var type in listType)
{
Console.WriteLine(ListClass<type>.getValues());
}
}
Here's how:
public void testMethod()
{
foreach (var type in listType)
{
Console.WriteLine(
(bool)typeof(ListClass<>)
.MakeGenericType(type)
.GetMethod("getValues")
.Invoke(null, new object[] { }));
}
}
Now I don't know if this is the code you need because you didn't post the example that I was asking for. Nevertheless, I hope this helps.
I did this kind of class in the past and I can't remember exactly how..
Say you have this class :
public class TestMethod
{
private string a, b, c, d, e;
public void SetA(string text) => a = text;
public void SetB(string text) => b = text;
public void SetC(string text) => c = text;
public void SetD(string text) => d = text;
public void SetE(string text) => e = text;
public void Print()
{
Console.WriteLine(string.Format("A: {0}\nB: {1}\nC: {2}\nD: {3}\nE: {4}\n", a,b,c,d,e));
}
}
And you would like to call it like so:
TestMethod method = new TestMethod();
method.SetA("").SetB("").Print();
What do I need to add to my class and what is this called ?
This is called a call-chain. You have to add a return this statement.
public class TestMethod
{
private string a, b, c, d, e;
public TestMethod SetA(string text) { a = text; return this; }
public TestMethod SetB(string text) { b = text; return this; }
public TestMethod SetC(string text) { c = text; return this; }
public TestMethod SetD(string text) { d = text; return this; }
public TestMethod SetE(string text) { e = text; return this; }
public void Print()
{
Console.WriteLine(string.Format("A: {0}\nB: {1}\nC: {2}\nD: {3}\nE: {4}\n", a,b,c,d,e));
}
}
Here is my code:
private int pressedMain = 1;
public int PressedMain
{
get
{
return pressedMain;
}
set
{
pressedMain = value;
}
}
And then I change the value of pressedMain:
pw.PressedMain++;
But in the following class my value is one, why and how can I slove this problem?
Example invoke, console prints 2 here
public class Foo
{
private int pressedMain = 1;
public int PressedMain
{
get
{
return pressedMain;
}
set
{
pressedMain = value;
}
}
}
class Program
{
static void Main(string[] args)
{
Foo foo = new Foo();
foo.PressedMain++;
Console.WriteLine(foo.PressedMain);
Debugger.Break();
}
}
Due to the polymorphism property of the classes, below example will print AB twice, which is expected.
In my case, I really want it to print A then AB.
I decided to change the Get() method in B from overrides to new.
This solves my problem, but they informed me of bad practise, so I'm looking for an alternative...
The one thing that comes to mind is to instantiate a new A in B.Do(), which I think is also bad practise...
//ORIGINAL
class Program
{
static void Main(string[] args)
{
var b = new B();
b.Do();
}
}
public class A
{
public virtual void Do()
{
var get = Get();
Console.WriteLine(get);
}
public virtual string Get()
{
return "A";
}
}
public class B : A
{
public override void Do()
{
base.Do();
var get = Get();
Console.WriteLine(get);
}
public override string Get()
{
return base.Get() + "B";
}
}
//UPDATED, USING NEW
class Program
{
static void Main(string[] args)
{
var b = new B();
b.Do();
Console.ReadLine();
}
}
public class A
{
public virtual void Do()
{
var get = Get();
Console.WriteLine(get);
}
public virtual string Get()
{
return "A";
}
}
public class B : A
{
public override void Do()
{
base.Do();
var get = Get();
Console.WriteLine(get);
}
public new string Get()
{
return base.Get() + "B";
}
}
Instead of calling the base version of Do in B.Do, you can change the implementation as follows:
public class B : A
{
public override void Do()
{
// Call the base version of Get explicitly
var getBase = base.Get();
Console.WriteLine(getBase);
// Call the current implementation of Get
var get = Get();
Console.WriteLine(get);
}
public override string Get()
{
return "B";
}
}
This will technically solve your problem, but is not a really clean solution from an OOP point of view. I suggest to think a bit about whether you need to be able to override Get independently. Maybe changing the signatures of your methods so that Get always returns a list of strings that should be printed is also a good solution (I've renamed Get to GetLines to reflect the changed purpose of the method):
public class A
{
public virtual void Do()
{
var lines = GetLines();
foreach(var line in lines)
Console.WriteLine(line);
}
public virtual IEnumerable<string> GetLines()
{
return new string[] { "A" };
}
}
public class B : A
{
public override IEnumerable<string> GetLines()
{
var lst = new List<string>(base.GetLines());
lst.Add("B");
return lst;
}
}
Here is the corrected code:
class Program
{
static void Main(string[] args)
{
var b = new B();
b.Do();
}
}
public class A
{
public virtual void Do()
{
Console.WriteLine(Get());
}
public virtual string Get()
{
return "A";
}
}
public class B : A
{
public override void Do()
{
Console.WriteLine(base.Get());
base.Do();
}
public override string Get()
{
return base.Get() + "B";
}
}
I want to do something like this:
public class Object1 {
public int number{get;set;}
}
public class Object2 {
public int number{get;set;}
}
public class Object3 {
public int number{get;set;}
}
main();
public void main(){
var objects1 = new List<Object1>{new Object1{number=1} , new Object1{number=2}};
test<Object1>(objects1);
}
public List<Object3> test<T>(IEnumerable<T> objs){
var rv = new List<Object3>();
foreach (var o in objs)
{
var foo = overloaded(o);
rv.Add(foo);
}
return rv;
}
public Object3 overloaded(Object1 obj){
// Run very specific things to Object1
return new Object3{number=obj.number+1};
}
public Object3 overloaded(Object2 obj){
// Run very specific things to Object2
return new Object3{number=obj.number+2};
}
You can directly run/edit the code here, with error handling:
http://csharppad.com/gist/6ff5f13cac8f0e5735be
The error I get is Argument 1: cannot convert from 'T' to 'Object1' - So how can I do this? The idea is that Object1 and Object2 have 95% of their code identical, it's that last 5% that I need to have it do something specific for each.
You could use dynamic to in your test method, just note that there are performance implications:
overloaded((dynamic)obj);
I would reverse your thinking.
Try this:
private void test<T>(T obj){
// Do common stuff
}
public void overloaded(Object1 obj){
test(obj);
Console.WriteLine("Do Object 1 stuff");
}
public void overloaded(Object2 obj){
test(obj);
Console.WriteLine("Do Object 2 stuff");
}
and call overloaded instead of calling test.
After playing around I was able to come up with this
public class Object1 {
public int number{get;set;}
}
public class Object2 {
public int number{get;set;}
}
public class Object3 {
public int number{get;set;}
}
main();
public void main(){
var objects1 = new List<Object1>{new Object1{number=1} , new Object1{number=2}};
test<Object1>(objects1);
}
public List<Object3> test<T>(IEnumerable<T> objs){
var rv = new List<Object3>();
foreach (var o in objs)
{
if(typeof(T) == typeof(Object1)){
rv.Add(overloaded((Object1)(object)o));
} else {
rv.Add(overloaded((Object2)(object)o));
}
}
return rv;
}
public Object3 overloaded(Object1 obj){
return new Object3{number=obj.number+1};
}
public Object3 overloaded(Object2 obj){
return new Object3{number=obj.number+2};
}
This works, but seems hacky to me. Wondering what the best way is!
Dependency Injection
interface IObject
{
int number {get;set;}
}
public class Object1 : IObject {
public int number{get;set;}
}
public class Object2 : IObject {
public int number{get;set;}
}
public class Object3 : IObject {
public int number{get;set;}
}
public IObject overloaded(IObject obj){
// Run very specific things to Object1
return new IObject {number=obj.number+1};
}