I am currently learning about Reflection in C#. I am calling 2 methods from a class using late binding. The first method (SumNumbers) works. The second method (SumArray) throws an exception saying "Parameter count mismatch". Can anyone kindly tell me how to pass an integer array to this method?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
namespace ReflectionWithLateBinding
{
public class Program
{
static void Main()
{
//load the current executing assembly
Assembly executingAssembly1 = Assembly.GetExecutingAssembly();
//load and instantiate the class dynamically at runtime - "Calculator class"
Type calculatorType1 = executingAssembly1.GetType("ReflectionWithLateBinding.Calculator");
//Create an instance of the type --"Calculator class"
object calculatorInstance1 = Activator.CreateInstance(calculatorType1);
//Get the info of the method to be executed in the class
MethodInfo sumArrayMethod1 = calculatorType1.GetMethod("SumArray");
object[] arrayParams1 = new object[4];
arrayParams1[0] = 5;
arrayParams1[1] = 8;
arrayParams1[2] = 2;
arrayParams1[3] = 1;
int sum1;
//Call "SumArray" Method
sum1 = (int)sumArrayMethod.Invoke(calculatorInstance, arrayParams1);
Console.WriteLine("Sum = {0}", sum1);
Console.ReadLine();
}
}
}
Class containing the 2 methods
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ReflectionWithLateBinding
{
public class Calculator
{
public int SumNumbers(int input1, int input2)
{
return input1 + input2;
}
public int SumArray(int[] input)
{
int sum = 0;
for (int i = 0; i < input.Length; i++)
{
sum += i;
}
return sum;
}
}
}
You're not passing an integer array to the reflected method, you're passing an object array with 4 integer values. This will cause reflection to want to find a method with 4 integer parameters. Instead, you want to pass the integer array as one of the values in your object array.
Change to this:
int[] numbers = { 5, 8, 2, 1 };
object[] arrayParams1 = { numbers };
I also want to point out that your Sum method isn't written correctly. You are just summing 0 to input.Length, and not the values present in the array.
You want
sum += input[i];
Finally, depending on why you want to do this, using dynamic in C# would be easier than using reflection and would ultimately result in the roughly the same type of exception scenarios (method not found on the object you are invoking the methods on).
dynamic calculatorInstance1 = Activator.CreateInstance(calculatorType1);
calculatorInstance1.SumArray(new int[] { 5,8,2,1 });
Edit, full working sample. The only thing I did was change your parameter array to my code above.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
namespace ReflectionWithLateBinding
{
public class Program
{
static void Main()
{
//load the current executing assembly
Assembly executingAssembly1 = Assembly.GetExecutingAssembly();
//load and instantiate the class dynamically at runtime - "Calculator class"
Type calculatorType1 = executingAssembly1.GetType("ReflectionWithLateBinding.Calculator");
//Create an instance of the type --"Calculator class"
object calculatorInstance1 = Activator.CreateInstance(calculatorType1);
//Get the info of the method to be executed in the class
MethodInfo sumArrayMethod1 = calculatorType1.GetMethod("SumArray");
int[] numbers = { 5, 8, 2, 1 };
object[] arrayParams1 = { numbers };
int sum1;
//Call "SumArray" Method
sum1 = (int)sumArrayMethod1.Invoke(calculatorInstance1, arrayParams1);
Console.WriteLine("Sum = {0}", sum1);
Console.ReadLine();
}
}
public class Calculator
{
public int SumArray(int[] input)
{
int sum = 0;
for (int i = 0; i < input.Length; i++)
{
sum += input[i];
}
return sum;
}
}
}
Related
I was trying to make a lucky dip program where 6 random numbers,1-59, are chosen then printed out in an array. I managed to get this to work, however you needed to use an IndexOf method so that no same number was printed twice by checking if the new number is already in the array.
using System;
namespace LuckyDip
{
class Program
{
static void Main(string[] args)
{
int[] luckyNumbers = new int[6];
Random random = new Random();
for (int x = 0; x<6; x++)
{
num[x] = random.Next(1,59);
Console.WriteLine(num[x]);
}
Console.ReadLine();
}
}
}
It prints out numbers, but sometimes they are the same.
You state that you want to use IndexOf, but that method is used for strings (see docs). Your example has an int array so the solution below uses Contains. This solution adds a check within your loop and generates a new number if this number already exists within your array. If you really need to use IndexOf, create a string array and convert the numbers using String.valueOf(randomNumber)
using System;
using System.Linq;
public class Program
{
public static void Main(string[] args)
{
int[] luckyNumbers = new int[6];
Random random = new Random();
for (int x = 0; x<6; x++)
{
int randomNumber = random.Next(1,59);
while (luckyNumbers.Contains(randomNumber))
{
randomNumber = random.Next(1,59);
}
luckyNumbers[x] = randomNumber;
Console.WriteLine(luckyNumbers[x]);
}
}
}
Another possible solution would be:
using System;
using System.Collections;
using System.Linq;
public class Program
{
public static void Main()
{
int arraySize = 6;
int[] luckyNumbers = Enumerable.Range(1,59).OrderBy(g => Guid.NewGuid()).Take(arraySize).ToArray();
for (int x = 0; x < luckyNumbers.Length; x++)
{
Console.WriteLine(luckyNumbers[x]);
}
}
}
This question already has answers here:
CS0120: An object reference is required for the nonstatic field, method, or property 'foo'
(9 answers)
Closed 6 years ago.
I'm facing the following error in C# Visual Studio that I just can't resolve:
"An object reference is required for the non-static field"
I don't know what it means nor how to fix it. Sure, I checked online but didn't find anything that spoke to my simple code below. All I want to do is call the following from Main() successfully:
int result = MaxPair(nums);
Many thanks in advance.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MaxPairSpace
{
class Program
{
static int Main(string[] args)
{
int n = Int32.Parse( Console.ReadLine() );
string input = Console.ReadLine();
string[] split = input.Split(' ');
int length = split.Length;
int[] nums = new int[length];
for (int x = 0; x < length; x++)
{
nums[x] = Int32.Parse(split[x]);
}
int result = MaxPair(nums);
Console.WriteLine("{0}\n", result);
return 0;
}
public int MaxPair(int[] numbers)
{
int result = 0;
int n = numbers.Length;
for (int i = 0; i < n; ++i)
{
for (int j = i; j < n; ++j)
{
if (numbers[i] * numbers[j] > result)
{
result = numbers[i] * numbers[j];
}
}
}
return result;
}
}
}
You cannot access a non-static method/Variable/Property directly inside a static method. To access such items you need to create an instance of the corresponding class and through that instance you can access them where as you can access other static methods/Variable/Property inside a static method. If such items belongs to a different class then You can access them through their class name. that is, ClassName.Method(). So better option here is to Change the method signature as like the following:
public static int MaxPair(int[] numbers)
{
// Code here
}
I wrote a C# code that will send functions ( 1-9) to a micro controller and the controller will send back data to my computer via RS232(SERIAL PORT). The problem that I am having is im trying to get the incoming data and put it in a sortedlist. The sorted list key will be date/time and the values will be the incoming data. I attempted to add the sortedlist portion to my code but it was unsuccessful. The errors i am getting are :
Error CS1503 Argument 2: cannot convert from 'int' to 'serialreadwrite.SMCValues'
CS0162 Unreachable code detected SMCData-
My code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Timers;
using System.IO;
using System.Net;
using System.Threading;
namespace serialreadwrite
{
public class SMCValues
{
public string ArrayVoltage;
public string ArrayCurrent;
public string AutoMPPT;
public string MotorVoltage;
public string ArrayAmps;
public string MaxMotorVoltage;
public string MotorRPM;
public string SerialNumber;
public string SMCType;
class Program
{
static void Main(string[] args)
{
SerialPort _serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
_serialPort.Handshake = Handshake.None;
_serialPort.ReadTimeout = 1000;
_serialPort.WriteTimeout = 1000;
_serialPort.RtsEnable = true;
_serialPort.DtrEnable = true;
_serialPort.Open();
for (int i = 0; i < 10; i++)
{
string c = Convert.ToString(i);
byte[] array_out = Encoding.ASCII.GetBytes(c); //convert i to the right variable type;
_serialPort.Write(array_out, 0, array_out.Length);
byte[] array_out2 = new byte[1];
array_out2[0] = 0xD;
_serialPort.Write(array_out2, 0, array_out2.Length);
//print what you receive
int k = 0;
int reader = 0;
string fullstring = "";
while (k < 23)
{
reader = _serialPort.ReadByte();
fullstring += Convert.ToChar(reader);
k++;
DateTime cur = DateTime.Now;
SortedList<DateTime, SMCValues> mySL1 = new SortedList<DateTime, SMCValues>();
Console.WriteLine(" (mySL1):");
while (true)
{
for (int j = 0; j < 10; j++)
{
string p = Convert.ToString(j);
cur = DateTime.Now;
mySL1.Add(cur, j); // j is throwing the errror
System.Threading.Thread.Sleep(1000);
}
foreach (KeyValuePair<DateTime, SMCValues> kvp in mySL1)
{
Console.WriteLine("my first key is = {0}, and my first value is = {1}", kvp.Key, kvp.Value);
}
Thread.Sleep(5000);
}
Console.WriteLine(fullstring);
_serialPort.DiscardInBuffer();
_serialPort.DiscardOutBuffer();
}
Console.ReadLine();
}
}
}
}
}
You are trying to assign an integer value 'j', to a 'SMCValues' which is a class.
It seems from your question that you are initially trying to verify that you can get a sorted list of dates to work, so you can temporarily make the following change:
//SortedList<DateTime, SMCValues> mySL1 = new SortedList<DateTime, SMCValues>();
SortedList<DateTime, int> mySL1 = new SortedList<DateTime, int>();
You will need to change your foreach as well.
Then later when you are ready, swap back to the original declaration and make sure you are using 'SMCValues' in your .Add statement
In my project that i'm working on I have to match 5 numbers for yahtzee. So all these numbers have to be the same. Now I have thought about how to do this but i'm not sure about what the best and easiest way is. Sure I can write it all out but there has to be a shorter way.
I haven't written the code for the part that checks if yahtzee has been thrown. This is because I only can come up with one way and that is to write it all out.
Here's my code so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Opdr3
{
class Program
{
struct YahtzeeGame
{
public int[] dobbelstenen;
public Random rnd;
public void Gooi()
{
for (int i = 0; i < 5; i++)
{
dobbelstenen[i] = Int32.Parse(rnd + "");
}
}
public bool Yahtzee()
{
Here it has to check if all dobbelstenen[int]
are the same
}
}
static void Main(string[] args)
{
// maak YahtzeeGame (struct) aan
YahtzeeGame yahtzeeGame;
// initialiseer struct-members
yahtzeeGame.rnd = new Random();
yahtzeeGame.dobbelstenen = new int[5];
// probeer yahtzee te gooien
int aantalPogingen = 0;
do
{
// gooi alle dobbelstenen
yahtzeeGame.Gooi();
aantalPogingen++;
} while (!yahtzeeGame.Yahtzee());
// vermeld aantal pogingen voor yahtzee
Console.WriteLine("Aantal pogingen nodig: {0}", aantalPogingen);
// wacht op gebruiker
Console.ReadKey();
}
}
}
You'll need a little loop:
public bool Yahtzee()
{
// check if all dobbelstenen[int] are the same
for(int i = 1; i < 5; i++) // start with second dobbelstenen
{
if(dobbelstenen[i] != dobbelstenen[0]) return false;
}
return true;
}
It simply compares second, third, ... against the first.
I'm having trouble with this method return of the largest integer, compiler says no errors but it won't let me run it
I have no clear idea what you are asking for.. I think at one time you had code but it is now gone?
Anyway, here is a console example for making an array and displaying its max value.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
//Declare i
int i;
Console.WriteLine("Please enter 5 random numbers");
//Make some array
string[] numbers = new string[5];
for (i = 0; i < 5; i++)
{
Console.Write("\nEnter your number:\t");
//Storing value in an array
numbers[i] = Console.ReadLine();
}
//ta da your array is now completed.. lets see what is the largest..
var converted = numbers.Select(int.Parse);
int largest = converted.Max();
//ta da
Console.WriteLine("The largest number is..." + (largest));
}
}
}