C# - var not behaving as expected in for loop - c#

I found a situation where using "var" caused unexpected results.
In the code below I was expecting X to be declared as datatype "long".
Why does X get declared as datatype "int" ? (which causes an infinite loop in this case)
long maxNumber = (long)int.MaxValue + 1;
long count = 0;
for (var X = 0; X < maxNumber; X++)
{
count++;
}

And why did you expect
var X = 0;
to infer datatype long?
Type inference for var variables looks at the type of the initial value, only. It doesn't consider usage.
Others are telling you how to control the type of 0, with a suffix. I say, if you want a particular type, go ahead and write
long X = 0;
This isn't really the sweet spot for var. Type inference is mainly for types which are hard to name (IEnumerable<KeyValuePair<string, Converter<TreeViewNode, IEnumerable<TreeViewNode>>>> anyone?) or can't be named at all, in the case of anonymous types, or if you want the type to automatically change to match the return type of some other function. Integral loop counters just don't benefit.

var X = 0
This is the line that declares X's type, regardless of how it's later used. When you specify a numerical literal without any suffixes, it will be an integer. Here's one possible solution.
var X = 0L

Related

Char to Ascii int conversion in Go Language

we have a project migration happening from C# .Net to Go language. I have completed most part of it but i am stuck at one place. In c#, i have a code,
(int)char < 31
How can i write this in Go language?
There is no "char" type in Go, the closest you can get is rune which is an alias for int32.
Being an alias of int32 means the types int32 and rune are identical and you can treat a rune like an int32 number (so you can compare it, add to it / subtract from it etc.).
But know that Go is strict about types, and you can't compare values of different types (in your answer you are comparing it with an untyped integer constant which is ok). For example the following code is a compile-time error:
var r rune = 'a'
var i int = 100
if r < i { // Compile-time error: invalid operation: r < i (mismatched types rune and int)
fmt.Println("less")
}
Should you need to convert a value of rune or any other integer type to another integer type (e.g. rune to int), you can use simple type conversion, e.g..
var r rune = 'a'
var i int = 100
if int(r) < i {
fmt.Println("less")
}
See related question: Equivalent of python's ord(), chr() in go?
I found answer my self with below change
var r rune
r = 'a' // char
r < 31
This worked for me

Why am I receiving a "call is ambigious" error when trying to user Math.Floor with an integer?

I've just made a small program that uses the Floor method:
public static void Main(string[] args)
{
int i;
decimal[] t = new decimal[30];
for(i=0; i<t.Length; i++)
{
t[i]=Math.Floor(i/6);
}
for(i=0; i<t.Length; i++)
{
Console.WriteLine(""+t[i]);
}
Console.ReadKey(true);
}
But it doesn't work. SharpDevelop returns this error:
The call is ambiguous between the following methods or properties: 'System.Math.Floor(decimal)' and 'System.Math.Floor(double)' (CS0121)
which is related to this line:
t[i] = Math.Floor(i/6);
Could someone explain me what's wrong?
Also: at first I tried writing int[] t = new int[30]; since my program only returns integers. But it returned a second error, saying that I should use the type decimal instead of the type int. I also tried to use the type float and the type double but it didn't work either. It seems only the type decimal works. I would also like to know why?
Could someone explain me what's wrong?
The compiler is telling you exactly what's wrong - the call is ambiguous. The fact that you're trying to use the result of the call to assign into a decimal array is irrelevant to the compiler - it only looks at the arguments to the method to try to work out what method you want to call.
The type of the expression i/6 is int, and that is convertible to both double and decimal, with neither conversion being "better" than the other, so the call is ambiguous. In fact, you don't really need the call at all - you're performing integer arithmetic anyway with the expression i / 6, which truncates towards zero - which is the equivalent to Floor for non-negative numbers. And you're only wanting to store integers anyway... All you need is:
public static void Main(string[] args)
{
// While "values" isn't a particularly descriptive name, it's better
// than "t"
int[] values = new int[30];
// Limit the scope of i - declare it in the loop header
for (int i = 0; i < values.Length; i++)
{
values[i] = i / 6;
}
// You don't need the index here, so use a foreach loop. Generally prefer
// foreach over for
foreach (int value in values)
{
// You don't need any string concatenation here...
Console.WriteLine(value);
}
Console.ReadKey(true);
}
The counter in your for loop is an integer.
An integer divided by an integer results in an integer.
Integers do not have a decimal portion, so calling Math.Floor is useless in the first place.
Because of this, there is no overload Floor(int).
An integer can be implicitly converted to double and decimal, both which have this overload.
Both are applicable and thus you get the following error.

Assign variable values inside method

I'm trying to get make method in which I can assign values to multiple variables. I don't know how many variables I will have, but I know their type. The variables can all be of different types though.
I have googled quite a bit about this, and am fairly sure that this can't be done with managed code. (Correct me if I'm wrong though)
I don't know much (read: anything) about unsafe code. Can it be done that way? Maybe pass in an array of pointers to the variables I want to initialise and do it that way?
I am basically looking for a way to pass an arbitrary number of mixed type variables to a method and assign their values inside the method... Is it pie in the sky?
EDIT 1:
Here is some code which I hope illustrates what I would like to achieve:
private void SomeMethod()
{
string a = string.empty;
int b = 0;
double c = 0;
object[] testObject = new object[] { b, c };
SetVariables(ref testObject);
}
public static void SetVariables(ref object[] Variables)
{
for (int i = 0; i < Variables.Length; i++)
Variables[i] = // The value the variable needs to have
}
After SetVariables has executed, a, b and c would be say:
a = "Some text"
b = 123
c = 1564.653
I am looking for a way to access the variables passed in as the parameter to SetVariables and modify their value. I guess that would mean accessing their storage location in memory, hence my thinking that I might need pointers?
EDIT 2:
My question here should give a better indication of the context in which I am trying to do this.
I will only be dealing with basic types: string, int, double and bool for the variables I want to assign to.
The data I am assigning from is in text format and has a variable number of fields. Each field should map to one of the input variable in the order in which the variables are passed in. If the order does not match there will be a misasignment at best or a type error at worst, but it is up to the user to make sure that the variables match the data.
What you are trying to do doesn't work well in C#. It is really a language thing, not a "managed vs un-managed" thing.
It usually doesn't come up that much, because in your sample code, you do know that you have 2 variables. You had to type them to enter them into the array.
If SetVariables() is going to be called from a lot of places in the code with different numbers of parameters, you could make a bunch of overloads of the method (with 1 parameter, 2 parameters, 3 parameters, etc).
But really to be honest, typically when you run into this case it is because you are doing something in an un-wise way.
Thinking more about it, how would the line:
Variables[i] = // The value the variable needs to have
would be expected to work in this scenario. How does it know what to set an arbitrary variable to, since it can be of any type? Also, what stops it from messing up the variable assignments if I change the call from passing in variable b, c to reversing them c, b?
Logically, it starts to fall apart.
I guess what I'm trying to say is that C# doesn't support that very well, but it typically doesn't need to, because it rarely makes sense.
Trying to think of a working solution anyway; I would just have SetVariables just return the values, but not take in the parameters. It should be the other function's job to assign its variables. If you need to know the types, then just pass the types:
public object[] GetValues(params Type types)
{
var result = new object[types.length];
for (int i = 0; i < types.length; i++)
{
if(types[i] == typeof(string))
result[i] = "foo";
if(types[i] == typeof(int))
result[i] = -1;
}
return result;
}
public void DoStuff()
{
var data = GetValues(typeof(string), typeof(int), typeof(string));
string foo1 = (string)data[0];
int someNumber = (int)data[1];
string foo2 = (string)data[2];
}
Its ugly, but it works...
Here is an example adapted from this answer to a similar question, unfortunately your problem is a little difficult to solve and there really isn't a simple way to accomplish what you want.
private static void SomeMethod() {
string a = string.Empty;
int b = 0;
double c = 0;
SetVariables(x => a = (string)x
, x => b = (int)x
, x => c = (double)x);
Console.WriteLine("a: {0}\nb: {1}\nc: {2}", a, b, c);
}
public static void SetVariables(params Action<object>[] setters) {
var tokens = new object[] { "Hello", 10, 14.235 };
for (int i = 0; i < setters.Length; i++)
setters[i](tokens[i]); // Assumed this is read and initialized properly
}
I'll admit this has a bit of a smell to it, but since you really have to account for a variable input it should get you closer to what you want without adding an excessive amount of complexity.
I think you are pretty close to the answer yourself. Assuming that the value assigned to the variable is only based off what type it is then assuming you use the code you posted above you can compare the value type with a typeof() check during your for loop:
if(Variables[i].GetType() == typeof(int)){
//...do stuff
}
//etc...until you have an if for each data type you expect you might find
here is a link to the typeof documentation
I'm assuming you have looked at how to use reference types but just in case look here

WebHeaderCollection, access by index

using the following code, all cause a compilation error (.net 2):
var headers = new WebHeaderCollection();
var a = headers[0];
var b = headers[(int)0];
const int FIRST_HEADER = 0;
var c = headers[FIRST_HEADER];
All fail with: The call is ambiguous between the following methods or properties: 'System.Net.WebHeaderCollection.this[System.Net.HttpRequestHeader]' and 'System.Net.WebHeaderCollection.this[System.Net.HttpResponseHeader]'.
I can understand to some extent why (a) would fail, as the overloads accept the HttpRequestHeader/HttpResponseHeader enums; but (b) and (c) are implicitly cast to type int.
The following works:
var headers = new WebHeaderCollection();
int index = 0;
var d = headers[index];
I only came across this when writing some tests, and needed the ability to prove that an expected header was added (and in my scenario would always be the only one!)
Why do i have to declare a variable of type int to use this overload?
In all cases, the expression is deemed to be "a constant expression with value zero" - which is implicitly convertible to any enum type.
Your later code works because you're effectively losing the const-ness, so that removes the implicit conversion.
In fact, there's a bug in the C# compiler around this, which means it treats any constant expression with value zero, not just integer values, as convertible to any enum type - so this works too, but shouldn't:
HttpRequestHeader weird = 0.0;

Using out keyword in c#

can anyone suggest me the exact use of out keyword as a paramter, and how its connected for returning multiple values from the function, as in this POST, i am confused with out variable with normal variable. can anyone help me for this.
This is frequently confusing, and I think the MSDN documentation actually is a bit "clear only if already known". That is, it is correct, but it really only makes sense if you already understand the concept.
Here's how I think of it.
A regular parameter makes a copy of the value of the argument. When you say:
static int M(int z) { z = z + 1; return z; }
...
int x = 123;
int y = M(x);
That is just like you said:
int x = 123;
int z = x; // make a copy of x
z = z + 1;
int y = z;
A ref or out parameter make an alias for an existing variable. When you say
static void N(ref int q) { q = q + 1; }
...
int x = 123;
N(x);
That is the same as saying:
int x = 123;
// MAGIC: q is now an another name for variable x
q = q + 1;
q and x are two different names that refer to the same variable. Incrementing q also increments x because they are the same. z and x in the previous example are two different names that refer to two different variables. Incrementing z does not change x.
Summing up: "out" and "ref" just mean "do not make a new variable; rather, temporarily make a second name for an existing variable".
Is that now clear?
UPDATE: I did not say what the difference between "out" and "ref" is. The difference is simple. On the "caller" side, a "ref" must be a definitely assigned variable before the method is called. An "out" need not be. On the "callee" side, a "ref" may be read before it is written to, but an "out" must be written to before it is read. Also, an "out" must be written to before control leaves the method normally.
MSDN documentation already does a great job explaining this:
The out keyword causes arguments to be passed by reference. This is
similar to the ref keyword, except that ref requires that the variable
be initialized before being passed. To use an out parameter, both the
method definition and the calling method must explicitly use the out
keyword. For example:
class OutExample
{
static void Method(out int i)
{
i = 44;
}
static void Main()
{
int value;
Method(out value);
// value is now 44
}
}
It's very frequently used in a pattern that "tries" to get a value, something like:
int result;
if(Int32.TryParse("123", out result))
{
Console.WriteLine(result + 1);
}
out keyword should be used when you want to:
a) Allow your function to modify specific variable from calling code stack AND
b) enforce setting this variable value inside your function
MSDN is always a good place to start
In most languages c# included you can pass values in 2 ways, by value, by reference.
by value gives the method a copy of your data, so changing the data wont have any effect on the original data
by reference essentially gives the method the memory address of your data, so if the method modifies the data, it changes the original.
Out is a special type of ref, in that you do not need to initialise the variable before you call the method, it can be called with null being passed in. and it MUST be set by the method.
Another way you can think of it (from the outside code's point of view) is:
val = read only
ref = read/write
out = write only.
http://msdn.microsoft.com/en-us/library/t3c3bfhx(v=vs.80).aspx
out keyword is good if you want to return multiple values of pre-defined types (for example an int, a List<string> and a DateTime), and you don't want to create a new class just for this purpose.
Ok,
let look at the usual pattern for this kind of function - the TrySomething.
Suppose you have a function that might succeed giving you an value or not but you don't won't to use an exception for this because you don't want the overhead or it's a common trait.
Then you normaly return true if the method suceeded and false if not. But where would you put your outputvalue to?
One possible answer is using an out parameter like this:
bool TrySomething(MyInputType input, out MyOutputType output)
{
output = default(MyOutputType);
/* ... Try getting the answer ... */
if (!successful)
return false;
output = successfulOutput;
return true;
}
Remark:
Or you might consider using a Tuple<bool,MyOutputType> and indeed F# interpretes the pattern above as resulting in such a tuple by itself.

Categories

Resources