Help with incrementing intergers when looping in C# - c#

I have declared an int e.g. int i;
I have a method that is looped:
public static void NumberUp(int i)
{
i++;
System.Console.WriteLine(i);
...
}
although each time the number is returned, it is always 1. Not 1,2,3 and so on..
I would have imagined that "i" increases by one which each run of the method?

You can pass the variable by reference.
public static void NumberUp(ref int i)
{
i++;
System.Console.WriteLine(i);
...
}
This, however is bad design, as you now have a method with a side effect on the passed in parameter (which the method name doesn't indicate) - something that can catch other programmers by surprise.
It would be a better design to return the incremented value:
public static int NumberUp(ref int i)
{
return i + 1;
}

It's doing that because you're passing it by value. That means the variable within the function is a copy of the original.
If you want changes to reflect back to the original variable, you need to pass it by reference, meaning the variable refers to the original rather than a copy. You can use something like:
public static void NumberUp (ref int i) {
i++;
System.Console.WriteLine(i);
}

It would be better to define NumberUp like this
public static int NumberUp(int number)
{
System.Console.WriteLine(++number);
return number;
}
Then assign the return value in your loop.

int is a value type and not a reference type. As such, i inside NumberUp is a copy of the parameter you passed in.
If you want the value to be changed outside the method, pass the parameter as reference:
public static void NumberUp(ref int i)

This is reference vs value type. To accomplish what you actually need, you have to pass i by reference.

The Method is static but this does not automatically mean the parameter is.
Maybe use a static int in you class as member.
class x
{ static int i;
Or pass it byRef

Related

Pointers are unsafe but I don't understand ref

I want a singleton Problem with a "square" 2x2.
I want to be able to refer to the case by row.
I want to be able to refer to the row by case.
I know I could easily do this in C++ with pointers but it seems like a bad habit to do.
I don't understand how to link my "row" and my "case" together.
The same logic will be there for column but isn't describe in the code
The goal is so changing the value of a Case would affect the value reffered in the Row. How can I achieve this without pointer and with Ref?
class Program
{
static void Main(string[] args)
{
Problem.Instance().Show();
Problem.Instance().Change();
Problem.Instance().Show();
}
public class Problem
{
private Case[] cases = null;
private Row[] rows = null;
// same logic with private Column[] columns = null;
static Problem instance = null;
private Problem()
{
cases = new Case[4];
rows = new Row[2];
int i = 0;
for (i = 0; i < 4; i++)
cases[i] = new Case();
for (i = 0; i < 2; i++)
rows[i] = new Row(i);
}
public static Problem Instance()
{
if (instance == null)
instance = new Problem();
return instance;
}
public Case LinkToRow(int i, ref Row r)
{
cases[i].LinkToRow(r);
return cases[i];
}
public void Show()
{
rows[0].Show();
}
public void Change()
{
cases[0].Change();
cases[1].Change();
}
}
public class Row
{
private Case[] ref cases = null;
public Row(int i)
{
ref Row r = this;
cases = new Case[2];
cases[0] = Problem.Instance().LinkToRow(0, ref r);
cases[1] = Problem.Instance().LinkToRow(1, ref r);
}
public void Show()
{
Console.WriteLine("{0},{1}", cases[0].Val, cases[1].Val);
}
}
public class Case
{
private int val;
private ref Row r = null;
public Case()
{
}
public void LinkToRow(Row rr)
{
r = rr;
}
public int Val { get { return val; } }
public void Change()
{
val++;
}
}
}
In C#, private Row r = null; declares a rebindable reference to an instance of Row. ref is illegal there and not needed.
In C++, private: Row r; would be an instance of Row, not a reference. C++ is a different language with very different rules. C# classes can't "be on the stack"; they're always dynamically allocated, and the only way you can manipulate one is via a reference.
In C#, your private Row r; is already a reference. A C# reference is kind of like a pointer that you don't have to (and can't) explicitly dereference. Because it's always dereferenced, you can't do pointer arithmetic either. They're subject to many of the same polite fictions ("let's make them pretend it's not a pointer") as C++ references. Just take out ref.
A C# struct (e.g. System.DateTime) is more like a stack instance of a C++ class. This is very different from the C++ struct/class distinction.
The C# ref keyword is a different animal. Nothing to do with references.
In C#, the example below illustrates what the ref keyword is for: Passing references by reference instead of by value. That sounds like I'm pulling your leg but I'm not.
To explain it in terms of C++ semantics, passing a C# reference "by value" is like passing a pointer. You can change the object the caller's pointer points at, but you can't change the caller's pointer itself. You have only the value of the caller's pointer.
Passing a C# reference by reference is like passing in a pointer to a pointer: You can set (*p)->Foo = 3;, and you can also set *p = new Bar(); (I'm rusty on C/C++, corrections welcomed).
public static void F()
{
String x = "original value";
FByValue(x);
Console.WriteLine(x);
FByReference(ref x);
Console.WriteLine(x);
}
public static void FByValue(String s)
{
s = "different value for local copy of parameter only";
}
public static void FByReference(ref String s)
{
s = "different value for caller's copy, thanks to ref keyword";
}
ref works only with parameters, never ever with fields; see MSDN for more detail.
Lastly: FByValue() and FByReference() would have identical semantics with int instead of String.
In C# there is a difference between value types and references.
First, there is nothing wrong with pointers in C/C++, that's how the language works and, that's how the hardware works as well. They can just be confusing to the new user.
In C#, the definition of structures and classes is different than C++:
if you define your data structures as struct or as class.
A struct is an object that gets copied around as it is passed from calls to calls. A class on the other hand gets its pointer passed around, similar to a C++ pointer, so if you have references to class instances in C#, you're really referencing the same object, and changes done at one place will be reflected everywhere you hold a reference to that object.

Property setter not accessed when the property changed by external class

I have a public class that is is used to create a dll. It has a variable and a property. Let`s assume it looks like this:
public class Main
{
private int _someInt = 0;
public int SomeInt
{
get { return this._someInt; }
set
{
this._someInt = value;
if (this._someInt == 1)
{
_someInt = 0;
}
}
}
public int ExecuteMain()
{
OtherClass.DoSomething(this.SomeInt);
}
}
I also have another class, in a separate project in the OtherClass class, that has the static DoSomething method:
public static void DoSomething(int someInt)
{
someInt = 1;
}
My problem is that SomeInt property in the Main class is getting set to 1 by the DoSomething method of OtherClass, but this does not trigger the setter in the Main class' property. Am I doing something wrong?
What you are doing is passing SomeInt by value to the DoSomething method, which gets a copy of the int and just changes its local value.
You can:
Pass by ref: public static void DoSomething(ref int someInt)
Pass the Main class and change the value inside DoSomething:
public static void DoSomething(Mainclass main)
{main.SomeInt = 1}
There is no way of doing this,even if you pass the field by reference using ref keyword it's not gonna work because your property has a setter method not your field.You should be changing the value of your property, in order to execute the setter method and perform the validation.
You can do that,passing the current instance of your class instead of the field, for example:
public int ExecuteMain()
{
OtherClass.DoSomething(this); // just pass current instance using 'this'
}
public static void DoSomething(Main obj)
{
obj.SomeInt = 1;
}
If you want to have it invoke the setter logic, one option is to do something like this:
public static void DoSomething(Action<int> setSomeInt)
{
setSomeInt(1);
}
then call it like this:
public int ExecuteMain()
{
OtherClass.DoSomething(x => this.SomeInt = x);
}
The concept here is that what you're really giving the method is not a variable that can be set, but rather an action that can be performed. This is an important distinction, as setting a property is really a kind of action, which can have an arbitrarily complex implementation. This approach is a bit awkward in practice, though, so you'll want to think carefully about what you're really trying to do here and whether there's a better way to express the desired dependency.

Access method via instance and static

Is it possible to create a class that has a method definition where the method can be accessed statically, and also be accessed via an instance of the class, without having to have two separate names for the method or a separate set of arguments to distinguish the methods as two different methods.
i.e.
public class MyClass
{
public static int GetMyInt()
{
return 1;
}
}
...
MyClass classInst = new MyClass();
int i = MyClass.GetMyInt();
int x = classInst.GetMyInt();
Is this possible in C#? If so, how so?
No. A method is static or is not.
I don't a valid use case you want to allow calling a static method against an instance of a class.
I dont think you can have the cake and eat the cake too.
Static (methods which are called through class) and non-static (methods which are called through instance of class ) are two opposite sides of a coin.
So either it is static or non-static but not both
A static (or class) method is by definition different from an instance method.
An instance method is only accessible when you create an instance of that class;
A static method is always accessible, since it doesn't require class instanciation (provided it is public), at least always accessible within the class itself. You should know, however, that if you have a static variable, any changes made to that variable will affect the class, and have an impact everywhere that variable is used on the application.
eg.
...
static int lastId;
public static int getLastId(){
return lastId++;
}
This is a way you may control an autonumber on a class, since whenever you call getLastId, lastId will be incremented and that is valid for all the application.
edit
the sample code illustrates what happens with a static variable. That said, you should know that overloading is supported on c#. What you cannot have is a pair of methods with the same name tag and the same set and type of parameters.
for eg., this builds ok.
public static int getValue()
{
return 1;
}
public int getValue(int x)
{
return x * 1;
}
but this will throw an error:
public static int getValue(int z)
{
return 1;
}
public int getValue(int x)
{
return x * 1;
}
that is true independently of wether there is a static method or not. This will also generate a compile time error:
public int getValue(int z)
{
return 1;
}
public int getValue(int x)
{
return x * 1;
}
even this will give you an error:
public string getValue(int z)
{
return 1;
}
public int getValue(int x)
{
return x * 1;
}
so, yes, you may have a static method with the same name tag of an instance method, but you may not have the same set and type of parameters.
If you want both static an instance methods to have the same behaviour, then why do you need the intance method really? The static method will do the trick (considering you know the consequences of having a static method and its implications).
Nope. But you can wrap it. But will have to give it a new signature.
public int getMyInt()
{
return GetMyInt();
}

How to pass references as arguments in a method in c#

How can you pass refernces in C#?
private void functionName (ref Type variableName)
{
}
To Call it
functionName(ref variable);
Your question is extremely unclear, but it's quite possible that my article on parameter passing in C# will answer whatever you really intended to ask.
In particular, you need to distinguish between passing a reference by value, and passing an argument by reference. If you're hazy on value types and reference types, you might also want to look at my article on that topic.
You can pass parameters by reference in C# using this syntax.
public void MyMethod(ref string myString)
{
}
You will then need to put ref before the value when passing it.
Jon Skeet has a good article on this here.
In C#, value types (like int, double, byte and structs) are passed by value, by default. This means that the receiving method has a NEW instance of the type. If an int that has a value of 1 is passed to the method, and the method changes it to 2, this change is only reflected within the method, the calling location's int is still 1. If however the ref keyword is added, then changes made to that integer are reflected back to the calling location.
All classes in C# are reference types. This means, by default, the references are passed by value. This is the important part. This means, changes made to that instance of the object are reflected back to the calling location, because it is the same object. However, if the method changes it's reference to a different object, this change is not reflected. In the case you want these changes reflected back, you would need to use the ref keyword on the parameter.
public static void Main()
{
int i = 1;
Method1(i); //i here is still 1
Method2(ref i); //i is now 2
SimpleObj obj = new SimpleObj();
obj.Value = 1;
Method3(obj); //obj.Value now 2
Method4(obj); // obj.Value still 2
Method5(ref obj); //obj.Value now 5
}
private static void Method5(ref SimpleObj obj)
{
obj = new SimpleObj();
obj.Value = 5;
}
private static void Method4(SimpleObj obj)
{
obj = new SimpleObj();
obj.Value = 5;
}
private static void Method3(SimpleObj obj)
{
obj.Value++;
}
private static void Method2(ref int i)
{
i++;
}
private static void Method1(int i)
{
i++;
}
public class SimpleObj
{
public int Value { get; set; }
}
The ref keyword is covered in section 10.6.1.2 of the C# 3.0 specification. Here is the msdn documentation.
Here is a nice overview of parameter passing in C#:
http://www.yoda.arachsys.com/csharp/parameters.html
Calling Code:
string companyName = "New Company";
GetEmail(ref companyName);
Method Code:
private void GetEmail(ref string companyName)
{
}
Your questions isn't clear, but I'd like to point out that in C#, objects are passed by reference by default. Meaning, if you have an object, and then pass that object on to a method that makes changes to that object, those changes will affect the object in your calling code as well, since they both reference the same object.

Can I pass parameters by reference in Java?

I'd like semantics similar to C#'s ref keyword.
Java is confusing because everything is passed by value. However for a parameter of reference type (i.e. not a parameter of primitive type) it is the reference itself which is passed by value, hence it appears to be pass-by-reference (and people often claim that it is). This is not the case, as shown by the following:
Object o = "Hello";
mutate(o)
System.out.println(o);
private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!
Will print Hello to the console. The options if you wanted the above code to print Goodbye are to use an explicit reference as follows:
AtomicReference<Object> ref = new AtomicReference<Object>("Hello");
mutate(ref);
System.out.println(ref.get()); //Goodbye!
private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }
Can I pass parameters by reference in
Java?
No.
Why ? Java has only one mode of passing arguments to methods: by value.
Note:
For primitives this is easy to understand: you get a copy of the value.
For all other you get a copy of the reference and this is called also passing by value.
It is all in this picture:
In Java there is nothing at language level similar to ref. In Java there is only passing by value semantic
For the sake of curiosity you can implement a ref-like semantic in Java simply wrapping your objects in a mutable class:
public class Ref<T> {
private T value;
public Ref(T value) {
this.value = value;
}
public T get() {
return value;
}
public void set(T anotherValue) {
value = anotherValue;
}
#Override
public String toString() {
return value.toString();
}
#Override
public boolean equals(Object obj) {
return value.equals(obj);
}
#Override
public int hashCode() {
return value.hashCode();
}
}
testcase:
public void changeRef(Ref<String> ref) {
ref.set("bbb");
}
// ...
Ref<String> ref = new Ref<String>("aaa");
changeRef(ref);
System.out.println(ref); // prints "bbb"
From James Gosling in "The Java Programming Language":
"...There is exactly one parameter passing mode in Java - pass by value - and that keeps things simple.
.."
I don't think you can. Your best option might be to encapsulate the thing you want to pass "by ref" onto another class instance, and pass the (outer) class's reference (by value). If you see what I mean...
i.e. your method changes the internal state of the object it is passed, which is then visible to the caller.
Java is always pass by value.
When you pass a primitive it's a copy of the value, when you pass an object it's a copy of the reference pointer.
Another option is to use an array, e.g.
void method(SomeClass[] v) { v[0] = ...; }
but 1) the array must be initialized before method invoked, 2) still one cannot implement e.g. swap method in this way...
This way is used in JDK, e.g. in java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[]).
Check out my response in: http://stackoverflow.com/a/9324155/1676736
In there I used a simpler version of the wrapper class idea.
I don't like setters/getters as a standard. When there is no reason to bury a field I make it 'public'. Especially in something like this.
However, this would work for all but the primitive, or multi-parameter/type returns:
public class Ref<T> {
public T val;
}
Although, I suppose you could just add more type parameters. But I think that creating an inner static class fit-for-purpose would be easier:
public static class MyReturn {
public String name;
public int age;
public double salary;
}
this would be for use when you don't need it for other reasons.
MyReturn mRtn = new MyReturn();
public void myMethod(final MyReturn mRtn){
mRtn.name = "Fred Smith";
mRtn.age = 32;
mRtn.salary = 100000.00;
}
System.out.println(mRtn.name + " " +mRtn.age + ": $" + mRtn.salary);

Categories

Resources