Use of unassigned out parameter, c# - c#

I have very simple problem.
I made a very simple function for you to demonstrate my problem.
static void Main(string[] args)
{
double[,] mydouble = new double[1, 4];
mynewMatrix(out mydouble);
}
public static void mynewMatrix(out double[,] d)
{
for (int i = 0; i < 4; i++)
d[0, i] = i;
}
Error:
Use of unassigned out parameter 'newMAt' The out parameter 'newMAt'
must be assigned to before control leaves the current method
I don't know where is problem.

If the array is defined OUTSIDE of the function, you should use a ref (or nothing, considering the array is a reference type). out means the parameter will be initialized in the function before it returns. Some examples of use:
static void Main(string[] args)
{
double[,] mydouble;
mynewMatrix(out mydouble);// call of method
double[,] mydouble2 = new double[1, 4];
mynewMatrix2(mydouble2);// call of method
// useless for what you want to do
mynewMatrix3(ref mydouble2);// call of method
}
public static void mynewMatrix(out double[,] d)
{
d = new double[1, 4];
for (int i = 0; i < 4; i++)
{
d[0, i] = i;
}
}
public static void mynewMatrix2(double[,] d)
{
for (int i = 0; i < 4; i++)
{
d[0, i] = i;
}
}
// useless for what you want to do
public static void mynewMatrix3(ref double[,] d)
{
for (int i = 0; i < 4; i++)
{
d[0, i] = i;
}
}
I'll add that if you don't know what is the difference between ref and out you could read Difference between ref and out parameters in .NET

In c# there are two very similar keywords, ref and out.
Both of them pass values by reference, but the difference is:
When you use ref the compiler will require you to assign your variable prior to calling the method.
When using out it will not require this. This means that you will not be able to assume that the parameter has already been populated. You will not be able to read its value inside the method.
To illustrate the problem, just imagine what would happen if someone else wrote this code to call your method:
double[,] myUnassignedDouble;
mynewMatrix(out myUnassignedDouble);
Clearly the variable will never be assigned, which is bad.
This leaves you with three options:
Assign the variable each time you call the method and use void mynewMatrix(ref double[,] d)
Assign the variable once, inside your method and use void mynewMatrix(out double[,] d)
Assign the variable each time you call the method and use void mynewMatrix(double[,] d)
The third option will work because so far you don't seam to need to reassign your variable. Obviously that might change as your code becomes more complicated. I assume you did have your reasons for using out in the first place?

The error message is clear - you need to assign a value to your out parameter inside your method:
public static void mynewMatrix(out double[,] d)
{
d = new double[1, 4];
for (int i = 0; i < 4; i++)
{
d[0,i]=i;
}
}
The assignment you made outside the method has no effect. Just write this:
static void Main(string[] args)
{
double[,] mydouble;
mynewMatrix(out mydouble);
}

You are assigning values to the elements of your array parameter, but you have to assign y value to the array itself because its defined as out:
d = new double[1, 4];

Related

C# - Efficient initialization of static array where every element is an output of function

Let's say I have a static function int foo(int i) and a static array long[] bar, both of which are declared before the main function. I could populate the array right away with elements: int[] bar = {foo(0),foo(1),foo(2)...}; (solution 1)
While compiler allows me to write this, it doesn't look pretty, especially for huge amount of elements.
Is there a way I could use a for cycle ?
A code such as for(int i = 0; i<bar.Length;i++) bar[i] = foo(i);
cannot be written "under" the declaration (solution 2), I need to write the code in the main function, (solution 3) and I guess I would lose the benefits of using static and pre-initialized stuff.
So, my question is: Is #1 more efficient than #3? Is #2 possible (for cycle outside the main class for initialization)?
You can use static constructor:
class MyClass
{
static readonly int[] bar;
static MyClass()
{
bar = new int[10];
for(int i = 0; i< bar.Length; i++) bar[i] = Foo(i);
}
static int Foo(int i) => i + 1;
}
Or LINQ with Enumerable.Range:
class MyClass
{
static readonly int[] bar = Enumerable.Range(0, 10)
.Select(Foo)
.ToArray();
static int Foo(int i) => i + 1;
}
You can use the LINQ methods:
static int[] bar = Enumerable.Range(0, 10).Select(i => foo(i)).ToArray();
Note that foo must be a static method for this to work, but whichever solution you pick for yout static field will require this anyway.
You can always just write a static method that returns the value with which you want to initialise bar:
static long[] bar = initBar();
static long[] initBar()
{
int n = 100;
var result = new long[n];
for (int i = 0; i < n; ++i)
result[i] = foo(i);
return result;
}

C# Generic method for random number generation

I see that there is a similar question for C++. Does anyone know why this method works when the method is non-generic, but as soon as I make it generic, the random number portion of code fails?
Error: Cannot implicitly convert type int to 'T'. If I can't use generics, I will have to rewrite the same function over and over for each different length of array.
public void fillGenericArray<T>(T[] inputArray) where T : IComparable
{
var randomNumb1 = new Random();
for (int i = 0; i < inputArray.Length - 1; i++)
{
Console.WriteLine($"{inputArray[i] = randomNumb1.Next(1, 501)},");
}
}
I had to look twice at this, but here's the issue:
Because inputArray is an 'array of type T'
then even though i is an int the expression
inputArray[i]
returns a type T not a type int.
And so, conversely, a type T must be assigned to it.
A generic method like this might achieve your goal:
public static void fillGenericArray<T>(T[] inputArray)
{
for (int i = 0; i < inputArray.Length; i++)
{
// Where T has a CTor that takes an int as an argument
inputArray[i] = (T)Activator.CreateInstance(typeof(T), Random.Next(1, 501));
}
}
(Thanks to this SO post for refreshing my memory about instantiating T with arguments.)
You could also use Enumerable.Range() to get the same result without writing a method at all:
// Generically, for any 'SomeClass' with a CTor(int value)
SomeClass[] arrayOfT =
Enumerable.Range(1, LENGTH).Select(i => new SomeClass(Random.Next(1, 501)))
.ToArray();
(Slightly Modified with help from this SO post) - see the answer using Enumerable.Range().
Here is a test runner:
class Program
{
static Random Random { get; } = new Random();
const int LENGTH = 10;
static void Main(string[] args)
{
Console.WriteLine();
Console.WriteLine("With a generic you could do this...");
SomeClass[] arrayOfT;
arrayOfT = new SomeClass[LENGTH];
fillGenericArray<SomeClass>(arrayOfT);
Console.WriteLine(string.Join(Environment.NewLine, arrayOfT.Select(field=>field.Value)));
Console.WriteLine();
Console.WriteLine("But perhaps it's redundant, because Enumerable is already Generic!");
arrayOfT = Enumerable.Range(1, LENGTH).Select(i => new SomeClass(Random.Next(1, 501))).ToArray();
Console.WriteLine(string.Join(Environment.NewLine, arrayOfT.Select(field => field.Value)));
// Pause
Console.WriteLine(Environment.NewLine + "Any key to exit");
Console.ReadKey();
}
public static void fillGenericArray<T>(T[] inputArray)
{
for (int i = 0; i < inputArray.Length; i++)
{
inputArray[i] = (T)Activator.CreateInstance(typeof(T), Random.Next(1, 501));
}
}
class SomeClass
{
public SomeClass(int value)
{
Value = value;
}
public int Value { get; set; }
}
}
Clone or Download this example from GitHub.
There is no reason to use generics. Just replace T with int and you will have function that does what you want (based on your question and comment below it).
EDIT: From your comment it seems you misunderstand the purpose of generics. The non-generic function WILL work for all lengths of the array.
And to answer why the change to generics fails. You are trying to assign int to generic type T which can be anything and compiler will not allow such a cast.

Cannot convert from void to bool when trying to use an array in my reverse function

Just as the heading states, I am trying to reverse a float array with my own reverse function.
The reverse function must not return a variable. The logic of the program may be off, so I am probably approaching this wrong.
Now the error I get is that it cannot convert from void to bool.
public static void reverse(float[] floatArr)
{
for (int i = 0; i < floatArr.Length; i++)
{
Console.WriteLine(floatArr[i]);
}
for (int i = 0; i < floatArr.Length / 2; i++)
{
float tmp = floatArr[i];
floatArr[i] = floatArr[floatArr.Length - i - 1];
floatArr[floatArr.Length - i - 1] = tmp;
}
}
static void Main(string[] args)
{
float[] floatArr = new float[5] { 5.6F, 6.4F, 4.2F, 3.6F, 8.4F };
Console.WriteLine(reverse(floatArr)); // cannot convert from void to bool
}
I know that I could fix this by having the reverse function be a float function and thus returning a float, but question stated that it must not return a value.
You are trying to print a function which returns type is void.
Console.WriteLine(reverse(floatArr)); // cannot convert from void to bool -> this is correct error
You should first call reverse(floatArr) and if the intention to print then you should loop on array to print the values. like as follows:
reverse(floatArr);
foreach(var val in floatArr)
{
Console.WriteLine(val);
}
This will print the values in different lines on console. If you want to print all values in one line then use the below line (credit to #LeonidVasilyev)
Console.WriteLine(string.Join(",", floatArr));

Generic Function: Cast T[] to Complex[]

I need a function that works on any either real-valued or complex-valued array.
However, for the function itself, it is very convenient to work on a Complex[]-Array. Therefore I want to typecast any array which is not of type Complex[] (e.g. double[] or byte[] or int[]...) to Complex[].
I thought this might be a nice exercise for myself to write a small generic function:
private static Complex[] convertArrayToComplex<T>(T[] inpArr)
{
if (typeof(T) != typeof(Complex[]))
{
Complex[] inpArrC = new Complex[inpArr.Length];
for (int k = 0; k < inpArr.Length; k++)
{
inpArrC[k] = new Complex((double)(object)inpArr[k], 0);
}
return inpArrC;
} else
{
return inpArr; // Compiler-Error is here
}
}
Of course this does not work: I get the Compiler-Error telling me, that T[] cannot implicitly casted to Complex[]. I do understand this, but I do not see a way to achieve my goal in an elegant fashion.
Constraints: I know that inpArr is a numeric Array.
You can know the type is equal, but you still have to convince the compiler. Also, I would make the code clearer by using is instead of type checking:
private static Complex[] convertArrayToComplex<T>(T[] inpArr)
{
if (inpArr is Complex[])
{
return (Complex[])(object)inpArr;
}
Complex[] inpArrC = new Complex[inpArr.Length];
for (int k = 0; k < inpArr.Length; k++)
{
inpArrC[k] = new Complex(Convert.ToDouble(inpArr[k]), 0);
}
return inpArrC;
}

type conversion error, c#

I am using Advanced Matrix Library in C#. NET#
http://www.codeproject.com/KB/recipes/AdvancedMatrixLibrary.aspx?msg=4042613#xx4042613xx.
library css file is like
using System;
namespace MatrixLibrary
{
public class Matrix
{
private double[,] in_Mat;
public Matrix(int noRows, int noCols)
{
this.in_Mat = new double[noRows, noCols];
}
public Matrix(double [,] Mat)
{
this.in_Mat = (double[,])Mat.Clone();
}
public static double[,] Identity(int n)
{
double[,] temp = new double[n,n];
for (int i=0; i<n;i++) temp[i,i] = 1;
return temp;
}
public static double[,] ScalarDivide(double Value, double[,] Mat)
{
int i, j, Rows, Cols;
double[,] sol;
try {Find_R_C(Mat, out Rows, out Cols);}
catch{throw new MatrixNullException();}
sol = new double[Rows+1, Cols+1];
for (i = 0; i<=Rows;i++)
for (j = 0; j<=Cols;j++)
sol[i, j] = Mat[i, j] / Value;
return sol;
}
}}
I am trying to get identity matrix and getting error of type conversion. Could some one please guide me.
Matrix id_mat = MatrixLibrary.Matrix.Identity(6);
Can't implicity convert typedouble[,] to Matrix.
But
Matrix B = new Matrix(4, 4);
Random rnd = new Random();
for (int i = 0; i < B.NoRows; i++)
for (int j = 0; j < B.NoCols; j++)
B[i, j] = 2 * rnd.NextDouble();
Matrix E = Matrix.ScalarDivide(2, B);
It works and I can Have a matrix. Please guide me?
regards,
Read the error message.
You have a method that returns double[,] and you are trying to store the reference in a variable for Matrix. There is no implicit conversion from a multidimensional array of doubles to a Matrix.
To use that method, you would write
double[,] id_max = MatrixLibrary.Maxtrix.Identify(6);
If you actually need to store it as a Matrix, you need to define the appropriate conversion to do so.
The function returns a 2D array "double[,]" and you're trying to assign it to a "Matrix". There isn't an implicit conversion that does this. Does Matrix have a constructor that accepts a "double[,]"? Maybe you could use that.
EDIT: You might also find that a different matrix library would suit you better than one pulled off of CodeProject. Math.NET Numerics is a good one that I've used that's also open source: http://numerics.mathdotnet.com/
You need an implicit cast.
public static implicit operator Matrix(double[,] m)
{
// code to convert
}

Categories

Resources