Why “this” cannot be set in C# [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I already checked the link "Why can't I set “this” to a value in C#?" and I know that this is read-only. In other words, it (the content) cannot be assigned to another new object. I am just wondering that the philosophy or the consideration of this constraint in C#. If the reason is about to the safety of memory management, C# employs garbage collector and the usage in the future to an object would be determined.
public class TestClass
{
private int Number;
public TestClass()
{
this.Number = 0;
}
public TestClass(TestClass NewTestClass)
{
this = NewTestClass; // CS1604 Cannot assign to 'this' because it is read-only
}
}
As the result, it seems that the members needs to be updated one by one.
public TestClass(TestClass NewTestClass)
{
this.Number = NewTestClass.Number; // Update members one by one.
}
Any comments are welcome.
Note: For clarifying, the C++ part has been removed.

I don't think you are quite familiar with what dereferencing a pointer is.
Let's look at this method:
void TestClass::SetThisTest() {
*this = TestClass(this->IncreaseNumber().GetNumber()); // Assign new object to *this
}
You believe you are replacing the this, but you aren't. You are replacing the contents pointed to by this. Huge difference. *this != this.
Try this:
void TestClass::SetThisTest() {
std::cout << "this' address is " << std::to_address(this) << std::endl;
*this = TestClass(this->IncreaseNumber().GetNumber()); // shallow copy!
std::cout << "Now this' address is " << std::to_address(this) << std::endl;
}
The address doesn't change, but, the values this points do does. You are invoking (in this case) default shallow copy.
You can do this in C# very easily, you just aren't allowed to be that direct about it.
Here is the C# equivalent of your C++ class:
public sealed class ThisTest
{
private int _myNumber;
public ThisTest() { }
public ThisTest(int number) { _myNumber = number; }
public static void ShallowCopy(ThisTest to, ThisTest from)
{
to._myNumber = from._myNumber;
}
public int GetNumber() => _myNumber;
public ThisTest IncreaseNumber()
{
_myNumber += 1;
return this;
}
public void SetThisTest()
{
ShallowCopy(this, new ThisTest(this.IncreaseNumber().GetNumber()));
}
}

Because "this" is a reference to the object you instantiated that is only accessible from the object itself.
Why would "this" need to be anything but self-referential?
var s = new Sample { Title = "My Sample" };
//in this case, I want to see a string representation of "s"
Debug.WriteLine(s.ToString());
//in this case, we might want a copy
var s2 = (Sample)s.MemberwiseClone();
public class Sample
{
public string Title { get; set; }
public override string ToString()
{
//it wouldn't make sense to reference another object's "Title", would it?
return this.Title;
}
}

Is a "keyword" in C# used to refer the current instance of the class.
You can't assign a value to keyword, another example is keyword "base" and we can't assign a value. E.g. base = "text".
We can assign a value to an object through another class that contains the first.
public class TestClassParent
{
private TestClass _testObject;
public TestClassParent(TestClass testOject)
{
this._testObject = testObject;
}
}

Related

How to change variable from one class using another in C# [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
The title may sound a bit confuse, but what I want to do is basicaly create a class,
declare a public int with the default value of 0, then inside the Program class I
permanently change the value of this variable in a function, and if I print this value using another function, it will print the value set in the first function.
For example:
using System;
{
class Global
{
public int variable = 0;
}
class Program
{
static void Main(string[] args)
{
Global test = new Global();
test.variable = 10;
//it makes no sense in this code to use another function,
//but in my other project it does
Function();
Console.ReadLine();
}
static void Function()
{
Global test = new Global();
//should print 10
Console.WriteLine(test.variable);
}
}
}
You could create a static class if you don't want to bother with injection like this:
public static class Global
{
public int variable = 0;
}
class Program
{
static void Main(string[] args)
{
Global.variable = 10;
}
static void Function()
{
Console.WriteLine(Global.variable);
}
}
or you could just inject the class through as a parameter from wherever you call it.
public class Global
{
public int variable = 0;
}
class Program
{
static void Main(string[] args)
{
var test = new Global();
test.variable = 10;
}
static void Function(Global global)
{
Console.WriteLine(global.variable);
}
}
If you want to permanently change this variable inside every class you could use a static class, but then you wouldn't be able to create instances of it (if you wanted other variables to be non-static.
I would recommend looking into IServiceProviders because they can be really useful if the Function() method is inside another class and you want to pass through the Global class.

Why can't you access parts of a class in C# like you could a struct in C++? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
namespace SnakesAndLadders
{
class Node
{
int snakeHead ; // points to another node where the player goes down to
int ladderFoot; // points to another node where to player goes up to
}
class Program
{
Node[] gameBoard = new Node[100];
void loadStructure()
{
// first, set all the snakeheads and ladderFoots to zero
for (int i =0; i < 100; i++)
{
gameBoard[i].snakeHead = 0;
gameBoard[i].ladderFoot = 0;
}
}
static void Main(string[] args)
{
}
}
In C#, this won't work. For gameBoard[i], intellisense does not show it has a component of snakehead.
In C# fields of a class are private by default
class Node
{
public int snakeHead ; // points to another node where the player goes down to
public int ladderFoot; // points to another node where to player goes up to
}
Just making your fields public should fix your issue.
EDIT: using best practices you would keep fields private, but create properties and use them to deal with your data. Also naming private with an underscore is a common practice:
class Node
{
private int _snakeHead ; // points to another node where the player goes down to
public int SnakeHead
{
get {return _snakeHead;}
set {_snakeHead = value;}
}
private int _ladderFoot; // points to another node where to player goes up to
public int LadderFoot
{
get {return _ladderFoot;}
set {_ladderFoot = value;}
}
}
Answer to your question:
In C++ fields of struct are public by default
In C# fields of struct are private by default
You have declared fields without access modifier keyword (private.public`) so they have default accessibility mentioned above.
To get same behavior in C# you need declare access modifier explicitly
struct Node
{
public int snakeHead ;to
public int ladderFoot;
}
Notice that in C++ fields of classes are private by default.
The default access modifier is private. Create properties to access your private fields.
class Node
{
int snakeHead ; // points to another node where the player goes down to
int ladderFoot; // points to another node where to player goes up to
public int SnakeHead
{
get { return snakeHead;}
set { snakeHead = value;}
}
public int LadderFoot
{
get { return ladderFoot; }
set { ladderFoot = value;}
}
}
After that you can gameBoard[i].SnakeHead = 0;
You can even define the properties like this:
public int SnakeHead{get; set;}
In this case you will not even need the private fields.

C# referencing a methods variables from another method [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Sometimes it happens that I want to use a lot of Method As variables in Method B.
Usually its quite a pain to pass all the variables to this method, especially if I have to do this a lot of times (but cannot simply copy paste, because some things change) or am just to lazy.
Is there such a thing like a "inner Method"? Or some concept to handle this in an easy way?
What I want to do:
public void A()
{
int a = 4;
string b = "Hello World";
B(ref vals);
//Or like so
C(ref current);
}
public void B(ref AllValues)
{
a = 3;
...
}
public void C(ref MethodThatSharesAllValues method)
{
method.a = 3;
...
}
If they all are in the same class
You can configure them as class variables:
public class MyClass{
//set this as private/protected/public or nothing and you can also set a default value
int a;
public void A()
{
a = 4;
string b = "Hello World";
B();
C();
}
public void B()
{
a = 3;
...
}
public void C()
{
a = 3;
...
}
}
Elseway
public static class MyClassA{
public static int a = 0;
public static void MethodA(){
this.a = 3;
}
}
now from method B you can access MyClassA
int myExValueA = MyClassA.a;
Elseway you gotta pass them as parameters
hope this helps
You can create a class which will hold your parameters and then pass only an instance of this class
public void metA(Parameters input)
{
input.a = 5;
input.c = "hello";
metB(input);
}
public void metB(Parameters input)
{
input.b = 10;
}
public class Parameters
{
public int a;
public int b;
public string c;
}
You can declare the variables static in a class header and use them as you like, private if are in the same class, protected for child classes, internal or public else. Or box the variables in a class like this:
public class Foo
{
public int A { get; set; }
public int B { get; set; }
public string C { get; set; }
}
If passed variables are the same type you can use data structure like int[] or string[] or List<int> or List<string> and pass them without ref but this has the disadvantage that more than often you would not use all varibales from the structure as it is also the case with the class boxing variant.
Something like the following:
public void foo() {
int a = 10;
// ...
}
public void foo_bar() {
// "a" is not in scope for foo_bar, so this won't compile
a = 20;
// ...
}
would definitely be invalid. I don't think that this was what you were driving at in your question though.
You can do something somewhat similar to what you ask for using closures but they're a bit tricky to work with. Basically, something like this would be valid (and I'm not sitting in front of an IDE so forgive me if the syntax is a little off):
Func<int> GetCounter() {
int count = 0;
// This will capture the count variable from its context
Func<int> method = () => ++count;
return method;
}
While a fair number of languages (including some versions of C++ now I guess) have closures (or some similar variant), there seems to be little consistency in exactly how they work across languages (e.g. on whether the "count" variable should be immutable once it's captured) so it's important to check the documentation for the language you're using (in this case, C#) to understand exactly how they work.
In terms of the first code sample I provide, I doubt that that's what you were asking about, but just as a brief digression you probably wouldn't really want it to be the allowable anyway (and again I suspect that this isn't the syntax/semantics you're asking about) as it would quickly lead to unexpected/undefined behavior. For example:
If you have a local variable a that's initialized in Foo() and you refer to it in Foo_Bar() before you run Foo(), what should its value be?
If you run Foo() to initialize the variable, edit the variable in Foo_Bar(), and then run Foo() again, should you re-initialize the variable or allow it to remain what Foo_Bar() set it to?
Is it safe to garbage collect a local variable after the method call completes, or might it be referred to again?
See the following:
public class SomeObject
{
public int SomeProperty { get; set; } = 6;
// ...
}
public class SomeOtherObject
{
// ..
}
void foo() {
// What is the content of "a" before foo() runs?
object a = new SomeObject();
// Which "a" should this refer to - the one in foo() or the one in foo_bar()?
// Also, is this a valid cast given that we haven't specified that SomeOtherObject can be cast to SomeObject?
var b = (SomeObject)a;
// If we run foo() again, should "b" retain the value of SetProperty or set it back to the initial value (6)?
b.SetProperty = 10;
// ...
// Is it safe to garbage collect "a" at this point (or will foo_bar refer to it)?
}
void foo_bar() {
object a = new SomeOtherObject();
// ...
}

Dictionary containing List [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
The below code:
public struct Value
{
List<string> RFcode;
int found;
int expected;
public int Found { get { return found; } }
public int Expected { get { return expected; } }
public List<string> Code { get { return RFcode; } }
public Value(int f, int exp, string s)
{
this.found = f;
this.expected = exp;
RFcode.Add(s);
}
}
is Invalid. On VS debug I get :
Error 1 Field 'BE_EOR.InvCyclic.Value.RFcode' must be fully assigned before control is returned to the caller
Error 2 Use of possibly unassigned field 'RFcode'
Please try this one:
List<string> RFcode = new List<string>();
The reason, why you get this error is the fact, that you haven't created a list, which will hold the strings you want. However, you try to add elements in this list:
RFcode.Add(s);
This line of code, List<string> RFcode;, it justs defines a variable called RFcode, that will keep a reference to a List of strings. Neither it creates a list nor it assings it to this variable.
Update
As already Christian Sauer has pointed out and Kensei have reminded it to us, it would be better you use a class rather than the struct you use:
public class Value
{
public List<string> RFCode { get; set; }
public int Found { get; set; }
public int Expected { get; set; }
public Value(string s, int found, int expected)
{
RFCode = new List<string> { s };
Found = found;
Expected = expected;
}
}
However, at this point I have to raise a question. Why are you using a List of strings, since you only pass a string to your constructor? If that's the case, to pass only a string, I don't think that's a good design, since you don't use the most appropriate type for that you want.

C# - How to access a static class variable given only the class type?

This is my first time posting on Stack Overflow, so hopefully I did everything right and you guys can help.
I'm wondering if in C# there's a way to access a static variable belonging to a class, when given only the type of the class. For example:
public class Foo
{
public static int bar = 0;
}
public class Main
{
public void myFunc(Type givenType)
{
int tempInt = ??? // Get the value of the variable "bar" from "Foo"
Debug.WriteLine("Bar is currently :" + tempInt);
}
}
// I didn't run this code through a compiler, but its simple enough
// that hopefully you should get the idea...
It's hard to describe the context of needing to know this, but I'm making a game in XNA and I'm trying to use reference counting to reduce the complexity of the design. I have objects in the game and power-ups that can apply an effect them (that stays on the objects). Power-ups can die but their effects can still linger on the objects, and I need to keep track of if any effects from a power-up are still lingering on objects (thus, reference counting). I plan to make a "PowerUpEffect" class (for each type of power-up) with a static integer saving the number of objects still affected by it, but the design of the rest of the game doesn't work well with passing the PowerUpEffect all the way down to the object for it to call a method of the PowerUpEffect class.
I'm hoping to pass only the PowerUpEffect's type (using something like "typeOf()") and use that type to reference static variables belonging to those types, but I have no idea how to do it or if it's even possible.
I'd be glad to even find work-arounds that don't answer this questions directly but solve the problem in a simple and elegant design. =)
Help! (and thanks!)
If you only have the Type handle, you can do this:
var prop = givenType.GetProperty("bar");
var value = prop.GetValue(null);
I would use a Dictionary instead, which are probably the most concise way of mapping one set of values to another. If you are associating int values with Types, then do something like:
public static readonly Dictionary<Type, int> sTypeValues =
new Dictionary<Type, int>
{
{ typeof(Type1), 5 },
{ typeof(Type2), 10 },
{ typeof(Type3), 2 },
{ typeof(Type4), 3 },
{ typeof(Type5), -7 }
};
your function then becomes:
public void myFunc(Type givenType)
{
int tempInt = sTypeValues[givenType];
Debug.WriteLine("Bar is currently :" + tempInt);
}
int tempInt = (int) givenType.GetField("bar").GetValue(null);
Okay, so you have a collection of powerups, and you want to have an integer associated with each of those powerups. Rather than having a lot of classes, each with a static integer, you can have a single static collection which holds onto all of the powerups and their associated integer values.
public static class MyPowerupInfo
{
public static Dictionary<PowerUp, int> PowerUps {get; private set;}
static MyPowerupInfo
{
PowerUps = new Dictionary<PowerUp, int>();
PowerUps.Add(*some power up object goes here*, 0);
//TODO add other power ups
}
}
Then to use it you can do something like:
int powerupCount = MyPowerupInfo.PowerUps[wickedAwesomePowerup];
or:
public static void IncrementPowerup(Powerup powerup)
{
MyPowerupInfo.PowerUps[powerup] = MyPowerupInfo.PowerUps[powerup]+1;
}
If am getting you correc, this might give you some idea:
using System;
using System.Reflection;
public class RStatic
{
private static int SomeNumber {get; set;}
public static object SomeReference {get; set;}
static RStatic()
{
SomeReference = new object();
Console.WriteLine(SomeReference.GetHashCode());
}
}
public class Program
{
public static void Main()
{
var rs = new RStatic();
var pi = rs.GetType().GetProperty("SomeReference", BindingFlags.Static | BindingFlags.Public); // i have used GetProperty in my case
Console.WriteLine(pi.GetValue(rs, null).GetHashCode());
}
}
Are you assuming if the name of the field you're trying to access (for example, for the class "foo", the field "bar") is a different field based on the Type parameter?
If the name of the field is known based on a finite number of allowable types, you should be able to determine it with a switch statement. For example:
public class Foo
{
public static int bar = 0;
}
public class Baz
{
public static int bing = 0;
}
public class Main
{
public void myFunc(Type givenType)
{
switch (givenType.ToString())
{
case "Foo":
Debug.WriteLine("Bar is currently :" + Foo.bar);
break;
case "Baz":
Debug.WriteLine("Bing is currently :" + Baz.bing);
break;
}
}
}

Categories

Resources