I'm new to c# (& coding in general) and i can't find anything pointer equivalent.
When i searched google i got something like safe/unsafe but that's not what i needed.
Like in c++ if you had a pointer and it pointed towards some value, the change in the pointer would cause change in the original variable.
Is there anything of such in c#?
example-
static class universal
{
public static int a = 10;
}
class class_a
{
public void change1()
{
universal.a--;
}
}
class class_b
{
public void change2()
{
some_keyword temp = universal.a; //change in temp gives change in a
temp-= 5; //the purpose of temp is to NOT have to write universal.a each time
}
}
...
static void Main(string[] args)
{
class_b B = new class_b();
class_a A = new class_a();
A.change1();
Console.WriteLine(universal.a);//it will print 9
B.change2();
Console.WriteLine(universal.a);//it will print 4
Console.ReadKey();
}
Edit-
thank you #Sweeper i got the answer
i had to use ref int temp = ref universal.a;
If you don't want unsafe code, I can think of two options.
Wrapper object
You can create a class like this, that wraps an int:
public class IntWrapper {
public int Value { get; set; }
}
Then change a's type to be this class:
static class Universal
{
public static IntWrapper a = new IntWrapper { Value = 10 };
}
class class_a
{
public void change1()
{
universal.a.Value--;
}
}
class class_b
{
public void change2()
{
Universal temp = universal.a; //change in temp gives change in a
temp.Value -= 5;
}
}
This works because classes are reference types, and a holds a reference (similar to a pointer) to a IntWrapper object. = copies the reference to temp, without creating a new object. Both temp and a refers to the same object.
ref locals
This is a simpler way, but it is only for local variables. You can't use this for a field for example.
public void change2()
{
ref int temp = ref universal.a; //change in temp gives change in a
temp -= 5;
}
C# has references which are very similar to pointers. If a and b are both references to the same object, a change in a will also be seen in b.
For example, in:
class X {
public int val;
}
void Main()
{
var a = new X();
var b = a;
a.val = 6;
Console.WriteLine(b.val);
}
6 will be written.
If you change the declaration of X from class to struct, then a and b will no longer be references, and 0 will be written.
In c# Pass By Reference is used instead of pointers, Here's the corrected code
static class universal
{
public static int a = 10;
}
class class_a
{
public void change1()
{
universal.a--;
}
}
class class_b
{
public void change2(ref int val)//use ref keyword for reference
{
int temp = val; //change in temp gives change in a
val -= 5;
}
}
static void Main(string[] args)
{
class_b B = new class_b();
class_a A = new class_a();
A.change1();
Console.WriteLine(universal.a);//it will print 9
B.change2(ref universal.a); //pass value by reference using ref keyword
Console.WriteLine(universal.a);//it will print 4
Console.ReadKey();
}
In some cases (when an optimization is very needed) you can use almost C-like pointers. You can only do that by explicitly specifying you are aware of the risk by placing your code in unsafe scope:
unsafe
{
int number = 777;
int* ptr = &number;
Console.WriteLine($"Data that pointer points to is: {number} ");
Console.WriteLine($"Address that pointer holds: {(int)ptr}");
}
The unsafe context allows you to use pointers directly. Please note that by default this option is turned off from your project. To test this you would need to right-click on project>Properties>Build - Allow unsafe code
Like this?
using System;
namespace Demo
{
class Program
{
static void Main()
{
var test = new class_a();
test.change1();
Console.WriteLine(universal.a); // Prints 18
}
}
static class universal
{
public static int a = 10;
}
class class_a
{
public void change1()
{
ref int x = ref universal.a;
++x;
++x;
++x;
x += 5;
}
}
}
[EDIT: I noticed that this is the same as the last part of Sweeper's answer, but I'll leave this here since it focusses just on that solution.]
Related
namespace Practice
{
public class LargestPrimeFactor {
public static void main(String[] args) {
readonly long NUM = 600851475143L;
int i;
int n;
int flag = 0;
long primeFactor = 1;
long factor = 1;
for(i=2; i<NUM/2; i++) {
flag = 0;
for(n=2; n < i/2; n++) {
if(i % n == 0) {
flag = 1;
}
}
if(flag == 0){
factor = i;
if(NUM % factor == 0) {
primeFactor = factor;
Console.WriteLine("factor = " + factor);
}
}
}
Console.WriteLine(primeFactor);
}
}
}
Please explain what I’m doing wrong. I don’t know how to declare this variable so that it is read-only. When I put it outside of the method, I get different errors.
The readonly modifier is valid at the class level, so you could refactor it as:
public class LargestPrimeFactor {
readonly long NUM = 600851475143L;
public static void main(String[] args) {
// ...
}
}
Alternatively, you can use the const keyword either at the field level or inside a method:
public class LargestPrimeFactor {
const long NUM = 600851475143L;
public static void main(String[] args) {
// ...
}
}
or
public class LargestPrimeFactor {
public static void main(String[] args) {
const long NUM = 600851475143L;
// ...
}
}
readonly is most useful for variables that will be fully initialized before the constructor completes but don't have a constant representation, e.g.
readonly DateTime startedAt = DateTime.Now;
You want to declare NUM as a const instead of a readonly.
If you read the documentation for readonly, you'll see that it doesn't apply to variables declared inside a method. The keyword can only be applied to:
readonly field declarations
readonly struct definitions
readonly instance members
ref readonly method return
If you want a variable that's defined inside a method to not be modified, you can declare it with the const keyword:
public static void Main(string[] args)
{
const long num = 600851475143L;
}
I wanted to do something similar, but for a value that was calculated at runtime. Instead of const long NUM = 600851475143L I used the new(ish) local function feature - not exactly const or readonly, but a way to lock down a value
long NUM() => someLongRuntimeValue;
. . .
for(i=2; i<NUM()/2; i++) {
. . .
This costs of a couple parentheses and a bit of runtime overhead - in my case the value was going to be used only a few times. It was a defensive code practice in a module edited by many people, a way of saying "I know you might think you want to change this value, but if you do you will break things" - my future self being one of the people I'm talking to.
I am trying to build a dummy exercise for my own interest.
I have one form (form1) with two textboxes (textBox1, textBox2) and a button.
When I click the button, I want to add the numbers passed to the textboxes.
Now, I am trying to complicate things by introducing an Interface with the signatures of the appropriate methods to do the addition (ICalculate) and a class (Calculations) which implements the interface.
Then I have another class called Calc which gets initiated from Form1 by passing an ICalculate object and 2 integers (a,b) in its constructor.
Furthermore, the Calc class has a method (addition()) for adding the two integers, using the ICalculate object and the two integers instantiated at the constructor of the class and display the result on a messagebox.
The problem is that the compiler throws an error saying that the ICalculate object has not been initialized (Object reference not set to an instance of an object.)
The code is the following:
public interface ICalculate
{
int add(int x, int y);
int sub(int x, int y);
}
class Calculations : ICalculate
{
public int add(int a, int b)
{
return (a + b);
}
public int sub(int z, int k)
{
return (z - k);
}
}
class Calc
{
private ICalculate _nc;
private int _x, _y;
public Calc(ICalculate nc, int a, int b)
{
var _nc = nc;
_x = a;
_y = b;
}
public void addition()
{
MessageBox.Show(_nc.add(_x, _y).ToString());
}
}
}
The Form1 Code is the following:
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var a = Int32.Parse(textBox1.Text);
var b = Int32.Parse(textBox2.Text);
var c = new Calc(new Calculations(), a, b);
c.addition();
}
}
Any help appreciated !
The problem is in the constructor of the Calc class.
Specifically, this row:
var _nc = nc;
You should remove the var:
_nc = nc;
What happens is that once you have the var keyword you are actually creating a local variable called _nc in the constructor, and assign the value of nc to it, so the class member called _nc is never initialized.
The compiler (tested on VS 2013) should issue a warning for this:
Field '<your namespace here>.Calc._nc' is never assigned to, and will always have its default value null
So I have a basic problem in unity:
public int A = 0;
int B = A;
This code throws an 'A field initializer cannot reference the nonstatic field, method, or property' error.
So I could do this:
public static int A = 0;
int B = A;
Which works, but then variable 'A' will not show up on the inspector. Can I have my cake and eat it too, having both a variable that can equal another and having it show up in the inspector? Thank you.
public int A = 0;
public int B;
void Start() {
B = A;
}
Solutions that could have worked in C#:
public const int A = 9;
int B = A;
And
public static int A = 9;
int B = A;
Static and constant variables cannot be displayed in Unity Editor. If you want to assign A to B, and still make it to show in the Editor, you have to do this in a function.
If you want B to always have the-same value as A throuout the program runtime,
public int A;
int B;
//Initialize A to B
void Start()
{
B = A;
}
//Make B always equals to A
void Update()
{
B = A;
}
Because the class is not static, your fields will not be initialized until you actually create an instance of the class for example.
public class Bot
{
public int a = 0;
public int b;
//If you try this it will not work
//public int b = a;
public Bot()
{
//This will work because once you create Bot, all fields will be initialized
this.b = a;
}
}
public static void Main()
{
//Once you create the class the Bot constructor will be called automatially
Bot botty1 = new Bot();
}
This question already has answers here:
Is it possible to pass properties as "out" or "ref" parameters?
(3 answers)
Closed 7 years ago.
I want to swap the field in the ConvexHull class just like swap( points[0], points[1] ).
How do I have to do?
public class ConvexHull
{
List<Point> points;
public void run ()
{
Point.swap ( ref points[ 0 ], ref points[ 1 ] ); //Error!!
}
}
public class Point
{
private double x, y;
Point () { x = y = 0; }
public static void swap(ref Point a, ref Point b) {
Point c = a;
a = b;
b = c;
}
}
When you index an element of List<T> you are actually accessing the this indexer, which is a kind of property (i.e. has getter and setter methods). You can only pass variables as ref or out, not properties.
In your scenario, perhaps you want something more like this:
public class ConvexHull
{
List<Point> points;
public void run ()
{
swap(0, 1); //No error!!
}
private void swap(int i, int j)
{
Point point = points[i];
points[i] = points[j];
points[j] = point;
}
}
A more general solution might look like this:
public class ConvexHull
{
List<Point> points;
public void run ()
{
points.SwapElements(0, 1);
}
}
static class Extensions
{
public static void SwapElements<T>(this List<T> list, int index1, int index2)
{
T t = list[index1];
list[index1] = list[index2];
list[index2] = t;
}
}
In either case, the correct approach is to provide the code that is actually swapping values with access to the List<T> object itself, so that it can access the indexer property to accomplish the swap.
Throw pretty much all of that away. You can't pass properties or list objects by ref. I notice there is nothing initially populating those points. Populate your List of Points, then call a function in your ConvexHull class to SwapPoints(int point1idx, int point2idx) and write the code there to do the swap.
On the Point class, expose X and Y, and drop the swap routine from there as it will never work.
In below example, i defined number field. This field will work as i wanted but it is not enough efficient to provide my expectations.
number value is fixed value for each class,number is not dependent instances and number support polymorphism. How can i do that ? Or is there another solution for not use unneccesary number field for instances ?
abstract class Main
{
public int number;
public virtual void dostuff(){
int x = number;
}
}
class Derived:Main
{
public ovverride void dostuff(){
int x = number;
}
}
You could just make the number a property and initialise is in each class constructor:
abstract class Main
{
public int number{get; private set;}
public void dostuff(){
int x = number;
}
}
class Derived:Main
{
public Derived()
{
number = 5; // Specific value for each derived class
}
public void dostuff(){
int x = number;
}
}
Looks like I got the wrong end of the stick -- you want to be able to set it statically per class type, which has already been answered.
You could make the property static and then add it to each class:
abstract class Main
{
public static int number;
public virtual void dostuff(){
int x = Main.number;
}
}
class Derived : Main
{
public static int number;
public overide void dostuff(){
int x = Derived.number;
}
}
Edit: I am a bit confused by your comments about polymorhism so i have added some more examples.
Main obj = new Derived();
obj.doStuff(); //This will use Derived.number; as doStuff is and overidden virtual method.
However if you do the following:
abstract class Main
{
public static int number;
public void dostuff(){
int x = Main.number;
}
}
class Derived : Main
{
public static int number;
public new void dostuff(){
int x = Derived.number;
}
}
Then you get different behaviour as below:
Main obj = new Derived();
obj.doStuff() // Will use Main.number
Derived obj2 = (Derived)obj;
obj2.doStuff() // Will use Derived.number
If you want some other kind of behaviour i havn't defined here please exaplin because i do not understand what you want.