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();
// ...
}
Related
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;
}
}
For example if I have Object.ObjectTwo.Property and I don't want to clutter my code by writing that all the time, is there a way to make it shorter?
Instead of writing Object.ObjectTwo.Property = something, I would like to be able to write myVariable = something.
I couldn't find anything when I tried searching.
Edit: The member in question is a property.
In C#, you can create shorthands for variable types at the global scope (where you put statements like using System;).
If you want to shorten Object.ObjectTwo to something simpler, you can use a using statement in the following manner:
using Object.ObjectTwo = ObjTwo;
Then, you can later call ObjTwo.Variable = someVar;, and it will act as if you had used Object.ObjectTwo.Variable = someVar;
Maybe just declare a separate variable?
var ObjectA = Object.ObjectTwo.Variable;
Though while this is more convenient for you, on the computer side, it is one more declared variable.
In C# 7, you can use Ref Locals. Unlike most other approaches, this approach can be used safely even when operating on structs.
This approach is only available on fields. Properties cannot be aliased using ref.
Below is an example.
struct bar
{
public int myprop;
}
struct bash
{
public bar mybar;
}
void Main()
{
bash bash1 = new bash();
bash1.mybar.myprop = 1;
Console.WriteLine(bash1.mybar.myprop); //Outputs 1 (Direct access)
bar bar2 = bash1.mybar;
bar2.myprop = 2;
Console.WriteLine(bash1.mybar.myprop); //Outputs 1 (Bug: access via a copy)
ref bar bar3 = ref bash1.mybar;
bar3.myprop = 3;
Console.WriteLine(bash1.mybar.myprop); //Outputs 3 (Ref Local)
bar3 = new bar();
bar3.myprop = 4;
Console.WriteLine(bash1.mybar.myprop); //Outputs 4 (Ref local with assignment)
}
You can give yourself some syntactic sugar by implementing "shortcuts" that might get you closer to your goal.
public class ObjectOne
{
public ObjectTwo ObjectTwo {get;set;}
public VariableType Var {get{return ObjectTwo.Variable;}}
}
This allows you to write for example:
var one = new ObjectOne();
one.Var = something;
#Eric Lippert is right, this is only one possible solution the Question needs more information to be answered correctly.
How about:
var shortCut = Object.ObjectTwo;
shortCut.Variable = something;
Use a local function (or on C# versions < 7.0 a delegate).
public void DoWork(SomeType thing, PropertyType value1, PropertyType value2)
{
void Shortcut(PropertyType value) => thing.ThingTwo.Property = value;
Shortcut(value1);
Shortcut(value2);
}
The example camera.backgroundColor.r = 1 from the comment simply won't work. You will get the following error
Cannot modify the return value of 'Camera.backgroundColor' because it is not a variable
and the reason has been discussed here. The point is that in Unity the Camera itself is the class but the Color (the type of the backgoundColor) is mutable struct, be careful though they are evil.
When you assign a new value to a variable of a value type, that value
is copied. When you assign a new value to a variable of a reference
type, the reference is copied, not the object itself
public class Camera
{
public BackgroundColorValue backgroundColorValue { get; set; }
= new BackgroundColorValue();
public BackgroundColorRef backgroundColorRef { get; set; }
= new BackgroundColorRef();
}
public struct BackgroundColorValue
{
public int r { get; set; }
public int g { get; set; }
public int b { get; set; }
}
public class BackgroundColorRef
{
public int r { get; set; }
public int g { get; set; }
public int b { get; set; }
}
var shortCutValue = cammera.backgroundColorValue;
var shortCutRef = cammera.backgroundColorRef;
shortCutValue.r = 5;
shortCutRef.r = 10;
//cammera.backgroundColorValue.r == 0, shortCutValue == 5
//cammera.backgroundColorRef.r == 10, shortCutValue == 10
The value types are copied by value so shortCutValue doesn't have any connection with the camera.backgroundColor.r except they have the same value in one period of their existance. On the other hand, shortCutRef is an actual shortcut and it will work until you change the reference to the backgroundColorRef which might be possible if Camera is mutable.
var shortCutRef = cammera.backgroundColorRef;
camera.backgroundColorRef = new BackgroundColorRef(); //link to shortcut broken
shortCutRef.r = 10;
//cammera.backgroundColorRef.r == 0, shortCutValue == 10
I am not sure if this is applicable in general, there might be some case Eric knows, but if you have A.B.C.D....N.r you could make a shortcut if N is actually reference type and to be sure the link with the shortcut will be unbreakable all types from N to A should be immutable. Otherwise, you could break a link somewhere.
This question already has answers here:
When do you use the "this" keyword? [closed]
(31 answers)
Closed 5 years ago.
The older apprentices in my company use "this." a lot.
Two weeks ago I started coding object-oriented and still don't get for what it is being used.
You need to understand what instance is first. Let's say you have an object:
public class House
{
public decimal Height { get; set; }
}
You can have multiple instances of it:
var smallHouse = new House { Height = 100M };
var bigHouse = new House { Height = 300M };
Each instance has its own value of Height. When you want to work with Height in a method of House, you need to refer to the current instance method is operating at (the one consumer called).
This can be done explicitly by using this as a special kind of variable that refers to this current instance:
public class House
{
public decimal Height { get; set; }
public bool IsItTooBig()
{
return this.Height > 200;
}
}
Or you can omit this and let C# guess that what you mean is the instance value:
public class House
{
public decimal Height { get; set; }
public bool IsItTooBig()
{
return Height > 200;
}
}
Programmers differ in opinion whether it's good or bad to be explicit there. If you follow capitalization conventions, you can distinguish instance state and method scope state (normal variables) by it.
There are cases where you absolutely need it, for example when you have naming conflict, or when you want to return current instance from a method:
public class House
{
public decimal Height { get; set; }
public House AddFloor()
{
Height += 100;
return this;
}
}
You should consider applying immutability in many of these cases though.
The keyword 'this' represents the instance of an object used to explicitly call a method, field or property of that instance.
Commonly used when your private fields have the same name as the parameters in a given method:
private string name;
public void SetName(string name) {
this.name = name;
}
When you want to refer to instance field within that class you use this, it can be omitted but there are cases it can not be omitted.
public class InstanceClass
{
int field = 10;
public void Method()
{
int field = 0;
Console.WriteLine(field); // outputs 0
Console.WriteLine(this.field); // outputs 10 because "this" refers to field.
}
}
if there is no declared local variable that conflicts with field name, "this" can be omitted.
public class InstanceClass
{
int _field = 10;
public void Method()
{
int field = 0;
Console.WriteLine(field);
Console.WriteLine(_field); // prefixed with _.
// no conflicts
// so "this" can be omitted.
}
}
another case where you can not omit this, is when you use indexer.
public class InstanceClass
{
private List<int> _source;
private int offset;
public int this[int index] // you use "this"
{
get => _source[index + offset]
set => _source[index + offset] = value;
}
public void Method()
{
var first = this[0]; // must use "this" to refer to indexer for this class.
}
}
"this" is used for calling constructor overloads too.
public class Foo
{
public Foo() : this(0)
{
Console.WriteLine("world");
}
public Foo(int param1)
{
Console.WriteLine("Hello");
}
}
//...
var foo = new Foo(); // outputs "Hello world"
"this" also refers to instance of class itself. so if you want to return instance of self you use this.
public class Foo
{
public Foo ReturnMe() // weird example.
{
return this;
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm looking for a differences between declarations to define an integer numbers and declarations for a fields.
EXAMPLE: Declaration 'int b;' can be declaration for the inetger number b or it can be the declaration for the private field b. As it looks like, it depends on where this declaration is situated.
I know, that typical declaration to define a field is 'private string field;'
In the code below in the class MyClass I can't declare the integer numbers, but just the fields. Why?
I wrote 'int b;' because I wanted to declare the integer number b, but I got the field b. Visual Studio shows me, that 'b' is the field.
using System;
class MyClass
{
int b;
public static int x = 20;
public static int y;
public static int z = 25;
public MyClass(int i)
{
x = i;
y = i;
z = i;
}
}
class MyClient
{
public static void Main()
{
Console.WriteLine("{0},{1},{2}", MyClass.x, MyClass.y, MyClass.z);
MyClass mc = new MyClass(25);
Console.WriteLine("{0},{1},{2}", MyClass.x, MyClass.y, MyClass.z);
Console.ReadLine();
}
}
All fields are variables, but not all variables are fields.
From the documentation,
A field is a variable of any type that is declared directly in a class or struct. Fields are members of their containing type.
Or, more simply, fields are variables that are associated only with the class or object itself, not with a specific method.
Thus, when you have int b = 7;, it is technically correct to call it a variable, but it's more specific to call it a field. It's the same way that it's technically correct to simply call a Porsche Boxter a car - it is, in fact, a car, but it's more descriptive (and, therefore, potentially more useful) to call it a Boxter.
Note in particular that the definition of a field says absolutely nothing about what else is included in the class. A field is a field regardless of what other content you do (or don't) have in the class (so, for example, the fact that MyClass doesn't have a Main method is completely irrelevant).
Fields can be distinguished from a local variable, which is declared inside a method and is associated only with that particular method. For example:
public class MyClass {
public int a = 10; // This is a field
int b = 20; // Also a field
public void MyMethod() {
int c = 30; // This is a local variable, NOT a field
}
}
Note, in particular, that c is not "declared directly in a class or struct" - it's declared inside a method. Thus, by definition it's not a field.
Based on the wording in your question, I feel that your understanding of using the words "variables" and "field" is misguided.
You seem to be calling:
"variables" as private fields
"fields" as public fields
Take a look at the below code block, to help:
class MyClass
{
int b = 7; // this is a private field
private int c = 8; // this is a private field
public int d = 10; // this is a public field
}
In addition, from the code above, you can now understand the reason why you are unable to access b. It is due to the private access modifier that is assumed. You need to change it to a public field.
So, what you'll want to get your code up and going quickly is change:
int b = 7;
to
public int b = 7;
and then you can change
public static void Main()
{
Console.WriteLine("{0},{1},{2}", MyClass.x, MyClass.y, MyClass.z);
MyClass mc = new MyClass(25);
Console.WriteLine("{0},{1},{2}", MyClass.x, MyClass.y, MyClass.z);
Console.ReadLine();
}
to
public static void Main()
{
Console.WriteLine("{0},{1},{2}", MyClass.x, MyClass.y, MyClass.z);
MyClass mc = new MyClass(25);
Console.WriteLine("{0},{1},{2}", MyClass.x, MyClass.y, MyClass.z);
Console.WriteLine("{0}", mc.b);
Console.ReadLine();
}
Take special note that public fields should usually be avoided in favor for properties, you can read more about that by doing a few searches online.
Additional Resources
Fields (C# Programming Guide)
static (C# Reference)
Static Classes and Static Class Members (C# Programming Guide)
Properties (C# Programming Guide)
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;
}
}
}