Explicitly refer to a parameter - c#

How do I explicitly refer to the parameter as opposed to the member variable?
static recursive{
public static List<string> output = new List<string>();
public static void Recursive(List<string> output){
...
}
}

An unqualified reference will always refer to the parameter because it is at a more local scope.
If you want to refer to the member variable, you need to qualify it with the name of the class (or this, for non-static member variables).
output = foo; // refers to the parameter
recursive.output = foo; // refers to a static member variable
this.output = foo; // refers to a non-static member variable
But you should probably change the name anyway. It makes your code much easier to read.
And you shouldn't have public static variables at all. All of the .NET coding style guidelines strongly recommend properties instead of exposing public fields. And since those are always camel-cased, this problem solves itself.

public static void Recursive(List<string> output){
...
}
The code in the block that refers to output will always be local & not the member variable.
If you wish to refer to member variable, you could use recursive.output.

When you are inside the Recursive static method output will point to the argument of the method. If you want to point to the static field use the name of the static class as prefix: recursive.output

Give your member variable another name.
The convention is to use Camelcasing on public static members.
public static List<string> Output = new List<string>();
public static void Recursive( List<string> output )
{
Output = output;
}

You can explicitly reference recursive.output to indicate the static member, but it would be cleaner to rename either the parameter or the member.

I know of no way to explicitly refer to a parameter. The way this is usually handled is to give member variables a special prefix such as _ or m_ so that parameters will never have exactly the same name. The other way is to refer to member variables using this.var.

public class MyClass {
public int number = 15;
public void DoSomething(int number) {
Console.WriteLine(this.number); // prints value of "MyClass.number"
Console.WriteLine(number); // prints value of "number" parameter
}
}
EDIT::
For static fields is required name of class instead of "this":
public class MyClass {
public static int number = 15;
public void DoSomething(int number) {
Console.WriteLine(this.number); // prints value of "MyClass.number"
Console.WriteLine(MyClass.number); // prints value of "number" parameter
}
}

Related

What is the point of the in modifier for classes

C# 7.2 introduces the in modifier for parameters which makes perfect sense for structs and in particular for readonly structs.
It is also allowed to use it for a reference type
void Method(in StringBuilder value) { }
As reference types are passed by reference by default, is the in in the example above just a redundant modifier?
value = null is forbidden when you use in, does it mean that it spares also the copy of the reference address by just passing the original reference to the heap location and blocking changes?
in is compiled to IL in exactly the same way as ref, except in argument is marked with IsReadOnly attribute.
That means in behaves exactly as ref, but compiler (not runtime) enforces that you don't assign value to in argument.
So, as you correctly pointed out - in referenece-type argument is passed by reference (which means reference is not copied and points to original location), but compiler prevents you from changing it. I don't really see much use for it for reference types, but it won't hurt to have that, at least for consistency.
Whilst the other two answers are correct that in parameters end up as ref parameters in the resultant IL, care should be taken with the claim that this prevents the value being copied. This only holds true for readonly structs.
To demonstrate this, consider the following piece of code:
using System;
public struct S1
{
public int A;
public void ChangeA(int a) => A = a;
}
public static class Program
{
static void Main()
{
var s1 = new S1 { A = 1 };
S1Foo(in s1);
Console.WriteLine(s1.A);
}
private static void S1Foo(in S1 s) => s.ChangeA(2);
}
Since we are passing s1 by reference, one might reasonably assume that S1Foo, in calling ChangeA would then change the contents of s1. This doesn't happen though. The reason being that the s1 value is copied and a copy is passed by reference, to prevent such modifications of structs via in parameters.
If we decompile the resultant IL, you see that the code ends up as:
public static class Program
{
private static void Main()
{
S1 s = default(S1);
s.A = 1;
S1 s2 = s;
Program.S1Foo(ref s2);
Console.WriteLine(s2.A);
}
private static void S1Foo([IsReadOnly] [In] ref S1 s)
{
S1 s2 = s;
s2.ChangeA(2);
}
}
However, if we write similar code using a readonly struct, then no copying occurs. I say similar as it isn't possible to write the same code as fields and property have to be readonly in a readonly struct (the clue is in the name):
using System;
public readonly struct S2
{
private readonly int _a;
public int A => _a;
public S2(int a) => _a = a;
public void ChangeA(int a) { }
}
public static class Program
{
static void Main()
{
var s2 = new S2(1);
S2Foo(in s2);
Console.WriteLine(s2.A);
}
private static void S2Foo(in S2 s) => s.ChangeA(2);
}
Then no copy occurs in the resultant IL.
So in summary:
in is effectively a readonly ref,
The value (or reference) is passed by reference,
The compiler prevents modifying fields and properties of that reference to help enforce its readonly-ness,
To further enforce the readonly nature of the parameter, then non-readonly structs are copied before a reference to the copy is passed to the method. This doesn't occur for readonly structs.
From what I understand from official documentation, it means that arguments passed to the method will not be changed inside the method itself:
The in keyword specifies that you are passing the parameter by reference and the called method does not modify the value passed to it.
when using the in keyword with value types, it means that instead of passing the argument by value (meaning creating a new copy of the value), it is passed by reference - so it avoids the unnecessary copying.
The only useful thing I can think of for in with reference types would be generic functions with constraints.
public interface IIntContainer
{
int Value { get; }
}
public readonly struct LargeStruct : IIntContainer
{
public readonly int val0;
public readonly int val1;
// ... lots of other fields
public readonly int val20;
public int Value => val0;
}
public class SmallClass : IIntContainer
{
public int val0;
public int Value => val0;
}
public static class Program
{
static void Main()
{
DoSomethingWithValue(new LargeStruct());
DoSomethingWithValue(new SmallClass());
}
public static void DoSomethingWithValue<T>(in T container) where T : IIntContainer
{
int value = container.Value;
// Do something with value...
}
}

Why an enum in an object instance has a static context?

I have the following class:
public class HandleResourceReferencesParams
{
public Factory Factory { get; set; }
public DataObject Resource { get; set; }
public HandleAction Action { get; set; }
public enum HandleAction
{
Activate,
Disable,
Terminate
}
}
Which is used in the following code:
var parameters = new HandleResourceReferencesParams();
parameters.Factory = context.Factory;
parameters.Resource = resource;
parameters.Action = parameters.HandleAction.Terminate; // Does not compile
HandleResourceReferences(parameters);
By using parameters.HandleAction, I get a compile error:
Cannot access static enum 'HandleAction' in non-static context
The enum is clearly not declared 'static'. Why does it have a static context when it is referenced from an object instance (non static as well)?
EDIT:
I already found the solution mentioned by Tim (Thanks by the way). I am just trying to understand why I am getting this error.
The error message is unfortunate, but it's not unfortunate that you can't do it... you're trying to access a member of a type, rather than a member of an instance of the type, but you're doing so "via" an instance.
Basically, it's the same reason that this code fails to compile:
Thread t = new Thread(...);
t.Start();
t.Sleep(1000); // Nope, Sleep is a static method
All nested types are effectively static members, in that you can't have a type which is specific to an instance of the containing type.
From the C# spec, section 10.3.7 (emphasis mine):
When a field, method, property, event, operator or constructor declaration includes a static modifier, it declares a static member. In addition, a constant or type declaration implicitly declares a static member.
So the enum is a static member of the type, despite not having the static modifier.
Use
parameters.Action = HandleResourceReferencesParams.HandleAction.Terminate;
You assign an enum to the instance-property, but the enum itself is like a static variable.
So you cannot call an enum through an instance of the outer class in which it is declared. This is similar to the compiler error if you try to use a static field through an instance of it's class:
public class FooClass
{
public static string Foo = "Foo";
public string FooProp { get; set; }
}
You cannot access the static field FooClass.Foo via instance either:
var foo = new FooClass();
foo.FooProp = foo.Foo; // does not compile either, you have to use FooClass.Foo
An enum consists of a set of named constants, const is static implicitly.
Why does the compiler don't let me use an instance? Because it tries to prevent you from obvious careless mistakes. You don't need an instance so don't use it.
I found how to make it compile, I am asking for the reason why it is not compiling how I did it
HandleAction.Terminate is a value of an enum.
Its value is not linked with an instance of HandleResourceReferencesParams but its a type nested in the object HandleResourceReferencesParams.
It is the definition of an enum, not a member like a property or variable which would be instantiated.
The only specificity of a nested definition (enum, struct or class) is its specific privileges with its parent class.

Confusion Regarding Default Constructor

using System;
class Test
{
string name;
int num1, num2;
public Test()
{
num1=10;
num2=20;
}
public void Show()
{
Console.WriteLine(num1+num2);
Console.WriteLine(name);
}
}
class TestDemo
{
static void Main()
{
Test ob = new Test();
ob.Show();
}
}
Confusion:
The Complete Reference C# 3.0 says that a default constructor will not be called if you define your own constructor. I did that thing, but left the string variable without initializing it with my defined constructor. Now according to above concept the string variable is not initialized and no default constructor will run to give it a default value because I have defined my own.
So, why it does not show an error, that string is not initialized with any value or something similar. Doesn't it show that it has been assigned a value from somewhere [default constructor of compiler]?
There's no such thing as an "uninitialized" field (whether static or instance). All fields are initialized with a default value (null for reference types, the "natural zero" for value types).
The compiler will give you a warning if you include a readonly field which isn't assigned a value in the constructor, as then it will always have that default value - but it's still initalized.
The compiler can only spot when a local variable is used without being definitely assigned. That's because the compiler has a lot more information about control flow within a method than between methods within a class. If you have one method which assigns a value to a field and another which fetches the value from the field, there's no way for the compiler to know which will be called first - whereas the rules of definite assignment allow it to analyze a method to spot potential flows where a variable is read without having been assigned a value first.
None of this really has anything to do with default constructors, by the way. The compiler only provides a default constructor if you don't provide any constructors at all - so in your Test class, there's no default constructor as such, because you've provided your own parameterless constructor. Even if the compiler did provide a default constructor, it would be exactly equivalent to:
public Test() {}
... the fields would still just have their default values.
Your constructor
public Test()
{
num1=10;
num2=20;
}
is same as
public Test()
{
}
If you want to initialize num1 and num2 , you can do it as below:
private int num1, num2; //public fields are not recommended
public Test(int numberOne, int numberTwo)
{
num1 = numberOne;
num2 = numberTwo;
}
and you can do initialization as below:
Test ob = new Test(10,20);

What is the meaning of "this" in C#

Could anyone please explain the meaning "this" in C#?
Such as:
// complex.cs
using System;
public struct Complex
{
public int real;
public int imaginary;
public Complex(int real, int imaginary)
{
this.real = real;
this.imaginary = imaginary;
}
The this keyword is a reference to the current instance of the class.
In your example, this is used to reference the current instance of the class Complex and it removes the ambiguity between int real in the signature of the constructor vs. the public int real; in the class definition.
MSDN has some documentation on this as well which is worth checking out.
Though not directly related to your question, there is another use of this as the first parameter in extension methods. It is used as the first parameter which signifies the instance to use. If one wanted to add a method to the String class you could simple write in any static class
public static string Left(this string input, int length)
{
// maybe do some error checking if you actually use this
return input.Substring(0, length);
}
See also: http://msdn.microsoft.com/en-us/library/bb383977.aspx
When the body of the method
public Complex(int real, int imaginary) {
this.real = real;
this.imaginary = imaginary;
}
is executing, it is executing on a specific instance of the struct Complex. You can refer to the instance that the code is executing on by using the keyword this. Therefore you can think of the body of the method
public Complex(int real, int imaginary) {
this.real = real;
this.imaginary = imaginary;
}
as reading
public Complex(int real, int imaginary) {
assign the parameter real to the field real for this instance
assign the parameter imaginary to the field imaginary for this instance
}
There is always an implicit this so that the following are equivalent
class Foo {
int foo;
public Foo() {
foo = 17;
}
}
class Foo {
int foo;
public Foo() {
this.foo = 17;
}
}
However, locals take precedence over members so that
class Foo {
int foo;
public Foo(int foo) {
foo = 17;
}
}
assigns 17 so the variable foo that is a parameter to the method. If you want to assign to the instance member when you have a method where there is a local with the same name, you must use this to refer to it.
Nate and d_r_w have the answer. I just want to add that in your code specifically the this. does in deed refere to the member of the CLASS to distinguish from the arguments to the FUNCTION. So, the line
this.real = real
means assign the value of the function (in this case, constructor) parameter 'real' to the class member 'real'. In general you'd use case as well to make the distinction clearer:
public struct Complex
{
public int Real;
public int Imaginary;
public Complex(int real, int imaginary)
{
this.Real = real;
this.Imaginary = imaginary;
}
}
The this keyword refers to the current
instance of the class and is also used
as a modifier of the first parameter
of an extension method.
this (C# reference) - MSDN
C# Keywords - MSDN
this references the instance of the class.
As most answers are mentioning " the current instance of a class", the word "instance" may be difficult for newbies to understand. "the current instance of a class" means the this.varible is specifically used in the class where it is defined, not anywhere else. Therefore, if the variable name also showed up outside of the class, the developer doesn't need to worry about conflicts/confusions brought by using the same variable name multiple times.
this is a variable which represents the current instance of a class. For example
class SampleClass {
public SampleClass(someclass obj) {
obj.sample = this;
}
}
In this example, this is used to set the "sample" property on someclass obj, to the current instance of SampleClass.
Refers to current instance of class

Store a reference to a value type?

I am writing a "Monitor" object to facilitate debugging of my app. This Monitor object can be accessed at run time from an IronPython interpreter. My question is, is it possible in C# to store a reference to a value type? Say I have the following class:
class Test
{
public int a;
}
Can I somehow store a "pointer" to "a" in order to be able to check it's value anytime? Is it possible using safe and managed code?
Thanks.
You cannot store a reference to a variable in a field or array. The CLR requires that a reference to a variable be in (1) a formal parameter, (2) a local, or (3) the return type of a method. C# supports (1) but not the other two.
(ASIDE: It is possible for C# to support the other two; in fact I have written a prototype compiler that does implement those features. It's pretty neat. (See http://ericlippert.com/2011/06/23/ref-returns-and-ref-locals/ for details.) Of course one has to write an algorithm that verifies that no ref local could possibly be referring to a local that was on a now-destroyed stack frame, which gets a bit tricky, but its doable. Perhaps we will support this in a hypothetical future version of the language. (UPDATE: It was added to C# 7!))
However, you can make a variable have arbitrarily long lifetime, by putting it in a field or array. If what you need is a "reference" in the sense of "I need to store an alias to an arbitrary variable", then, no. But if what you need is a reference in the sense of "I need a magic token that lets me read and write a particular variable", then just use a delegate, or a pair of delegates.
sealed class Ref<T>
{
private Func<T> getter;
private Action<T> setter;
public Ref(Func<T> getter, Action<T> setter)
{
this.getter = getter;
this.setter = setter;
}
public T Value
{
get { return getter(); }
set { setter(value); }
}
}
...
Ref<string> M()
{
string x = "hello";
Ref<string> rx = new Ref<string>(()=>x, v=>{x=v;});
rx.Value = "goodbye";
Console.WriteLine(x); // goodbye
return rx;
}
The outer local variable x will stay alive at least until rx is reclaimed.
No - you can't store a "pointer" to a value type directly in C#.
Typically, you'd hold a reference to the Test instance containing "a" - this gives you access to a (via testInstance.a).
Here is a pattern I came up with that I find myself using quite a bit. Usually in the case of passing properties as parameters for use on any object of the parent type, but it works just as well for a single instance. (doesn't work for local scope value types tho)
public interface IValuePointer<T>
{
T Value { get; set; }
}
public class ValuePointer<TParent, TType> : IValuePointer<TType>
{
private readonly TParent _instance;
private readonly Func<TParent, TType> _propertyExpression;
private readonly PropertyInfo _propInfo;
private readonly FieldInfo _fieldInfo;
public ValuePointer(TParent instance,
Expression<Func<TParent, TType>> propertyExpression)
{
_instance = instance;
_propertyExpression = propertyExpression.Compile();
_propInfo = ((MemberExpression)(propertyExpression).Body).Member as PropertyInfo;
_fieldInfo = ((MemberExpression)(propertyExpression).Body).Member as FieldInfo;
}
public TType Value
{
get { return _propertyExpression.Invoke(_instance); }
set
{
if (_fieldInfo != null)
{
_fieldInfo.SetValue(_instance, value);
return;
}
_propInfo.SetValue(_instance, value, null);
}
}
}
This can then be used like so
class Test
{
public int a;
}
void Main()
{
Test testInstance = new Test();
var pointer = new ValuePointer(testInstance,x=> x.a);
testInstance.a = 5;
int copyOfValue = pointer.Value;
pointer.Value = 6;
}
Notice the interface with a more limited set of template arguments, this allows you to pass the pointer to something that has no knowledge of the parent type.
You could even implement another interface with no template arguments that calls .ToString on any value type (don't forget the null check first)
You can create ref-return delegate. This is similar to Erik's solution, except instead of getter and setter it use single ref-returning delegate.
You can't use it with properties or local variables, but it returns true reference (not just copy).
public delegate ref T Ref<T>();
class Test
{
public int a;
}
static Ref<int> M()
{
Test t = new Test();
t.a = 10;
Ref<int> rx = () => ref t.a;
rx() = 5;
Console.WriteLine(t.a); // 5
return rx;
}
You can literally take a pointer to a value type using usafe code
public class Foo
{
public int a;
}
unsafe static class Program
{
static void Main(string[] args)
{
var f=new Foo() { a=1 };
// f.a = 1
fixed(int* ptr=&f.a)
{
*ptr=2;
}
// f.a = 2
}
}
class Test
{
private int a;
/// <summary>
/// points to my variable type interger,
/// where the identifier is named 'a'.
/// </summary>
public int A
{
get { return a; }
set { a = value; }
}
}
Why put yourself through all that hassle of writing complicated code, declaring identifiers everywhere linking to the same location? Make a property, add some XML code to help you outside the class, and use the properties in your coding.
I don't know about storing a pointer, don't think it's possible, but if you're just wanting to check its value, the safest way to my knowledge is to create a property of the variable. At least that way you can check its property at any time and if the variable is static, you wouldn't even have to create an instance of the class to access the variable.
Properties have a lot of advantages; type safety is one, XML tags another. Start using them!

Categories