What does the Underscore Signify in Code? - c#

I am reviewing the following code and cannot make sense of it. I know the syntax elements like the use of underscore to discard results, the new keyword, and using keywords. Is the first line of
amethod() superfluous?
Is this somehow equivalent to
MyClass myclass = new MyClass()
using aclasslibrary;
private async amethod()
{
_ = new MyClass();
MyClass myclass;
myclass = await classService.Getsomething();
if (myclass != null)
{
persist (myclass);
}
}
MyClass is defined as follows
namespace aclasslibrary
{
public class MyClass
{
public int id;
public SomeClass something;
}
}

The _ acknowledges that the left side of an equation is to be safely ignored. So its saying ignore the result of the new MyClass();.
It appears to be a rookie mistake from a new learner because the following line declares a reference holder, which is not initialized; and could actually use such an initialization.

Related

Why does a lambda expression preserve enclosing scope variable values after method terminates?

I was under the impression that lambda expression contexts in C# contain references to the variables of the parent function scope that are used in them. Consider:
public class Test
{
private static System.Action<int> del;
public static void test(){
int i = 100500;
del = a => System.Console.WriteLine("param = {0}, i = {1}", a, i);
del(1);
i = 10;
del(1);
}
public static void Main()
{
test();
}
}
outputs
param = 1, i = 100500
param = 1, i = 10
However, if this was true, the following would be illegal, because the lambda context would reference a local variable that went out of scope:
public class Test
{
private static System.Action<int> del;
public static void test(){
int i = 100500;
del = a => System.Console.WriteLine("param = {0}, i = {1}", a, i);
}
public static void Main()
{
test();
del(1);
}
}
However, this compiles, runs and outputs
param = 1, i = 100500
Which means that either something weird is going on, or the context keeps values of the local variables, not references to them. But if this was true, it would have to update them on every lambda invokation, and I don't see how that would work when the original variables go out of scope. Also, it seems that this could incur an overhead when dealing with large value types.
I know that, for example, in C++, this is UB (confirmed in answer to this question).
The question is, is this well-defined behaviour in C#? (I think C# does have some UB, or at least some IB, right?)
If it is well-defined, how and why does this actually work? (implementation logic would be interesting)
The concept of closures as they relate to the lambda syntax in C# is a very large topic and too large for me to cover everything in just this answer but let's try to answer the specific question here at least. The actual answer is at the bottom, the rest between is background needed to understand the answer.
What happens when the compiler tries to compile a method using anonymous methods is that it rewrites the method to some extent.
Basically, a new class is generated and the anonymous method is lifted into this class. It's given a name, albeit an internal one, so for the compiler it sort of transitions from an anonymous method into a named method. You, however, doesn't have to know or handle that name.
Any variables that this method required, variables that was declared besides the anonymous method, but in the same method that used/declared the anonymous method, will be lifted as well, and then all usages of those variables is rewritten.
There's a couple of methods involved here now so it becomes hard to read the above text so instead let's do an example:
public Func<int, int> Test1()
{
int a = 42;
return value => a + value;
}
This method is rewritten to something like this:
public Func<int, int> Test1()
{
var dummy = new <>c__DisplayClass1();
dummy.a = 42;
return dummy.<Test1>b__0;
}
internal class <>c__DisplayClass1
{
public int a;
public int <Test1>b__0(int value)
{
return a + value;
}
}
The compiler can handle all these funky names (and yes, they really are named with all the brackets like that) because it refers to things with id's and object references, the names are no longer an issue for the compiler. You, however, can never declare a class or a method with those names so there's no risk of the compiler generating a class that just happens to already exist.
Here's a LINQPad example that shows that a class I declared, although with less brackets in its names, looks identical to the one generated by the compiler:
void Main()
{
var f1 = Test1();
f1(10).Dump();
f1.Dump();
var f2 = Test2();
f2(10).Dump();
f2.Dump();
}
public Func<int, int> Test1()
{
int a = 42;
return value => a + value;
}
public Func<int, int> Test2()
{
var dummy = new __c__DisplayClass1();
dummy.a = 42;
return dummy._Test2_b__0;
}
public class __c__DisplayClass1
{
public int a;
public int _Test2_b__0(int value)
{
return a + value;
}
}
output:
If you look at the screenshot above you notice two things for each delegate variable, a Method property, and a Target property.
When calling the method, it is called with a this reference referring to the Target object. A delegate thus captures two things: Which method to call, and the object on which to call it.
So basically, that object of that generated class survives as part of the delegate because it is the target of the method.
With all that in mind, let's look at your question:
Why does a lambda expression preserve enclosing scope variable values after method terminates?
A: If the lambda survives, all the captured variables survive as well because they're no longer local variables of the method they were declared in. Instead they were lifted onto a new object that also has the lambda method, and thus "follows" the lambda everywhere it goes.

Static variable initialization using new gives a code hazard

I am working on some code which is something like this:
class A
{
static SomeClass a = new Someclass("asfae");
}
Someclass contains the required constructor.
The code for this compiles fine without any warning. But I get a code hazard in system:
"The Someclass ctor has been called from static constructor and/or
static initialiser"
This code hazard part of system just to make it better by warning about possible flaws in the system or if system can get into bad state because of this.
I read somewhere on the web that static constructor/initialiser can get into deadlock in c# if they wait for a thread to finish. Does that have something to do with this?
I need to get rid of this warning how can i do this.
I can't make the member unstatic as it's used by a static function.
What should I do in this case , Need help.
You could hide it behind a property and initialize it on first use (not thread-safe);
class A
{
static SomeClass aField;
static SomeClass aProperty
{
get
{
if (aField == null) { aField = new Someclass("asfae"); }
return aField;
}
}
}
or use Lazy (thread-safe):
class A
{
static Lazy<SomeClass> a = new Lazy<SomeClass>(() => new Someclass("asfae"));
}
...or this very verbose thread safe version :)
class A
{
static SomeClass aField;
static object aFieldLock = new object();
static SomeClass aProperty
{
get
{
lock (aFieldLock)
{
if (aField == null) { aField = new Someclass("asfae"); }
return aField;
}
}
}
}
By initialising it as a static field, it behaves as it would in a static constructor, i.e. it probably gets initialised the first time an instance of your class is instantiated, but might happen earlier. If you want more control over exactly when the field is initialised, you could use Lazy<T>, e.g.:
{
static Lazy<SomeClass> a = new Lazy<SomeClass>(() => new Someclass("asfae"));
}
This way, you know that the initialisation of SomeClass will only happen the first time the field is accessed and its Value property called.
I think to understand your problem you need to know the difference between static constructors and type initializers, there is a great article from Jon Skeet about this issue:
http://csharpindepth.com/Articles/General/Beforefieldinit.aspx
The point is that following constructions are not the same, and there are difference in the behavior:
class Test
{
static object o = new object();
}
class Test
{
static object o;
static Test()
{
o = new object();
}
}
In any case, you could try to create a static constructor for your class to be able to have more control on this initialization, and maybe the warning will disappear.
If the member is only used by a static method, and only by this one, I would recommend you to put it in the scope if this static method and not as class member.

Class with static instance inside

public class MyClass
{
// private fields
//////////////////////////////////////////////////////////////////////////
public MyClass(string param1, string param2)
{
// do some stuff
}
private static object syncRoot = new Object();
private static volatile MyClass instance = null;
public static MyClass Log
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new MyClass();
}
}
return instance;
}
}
private MyClass()
{
// do some stuff
}
public void myFunction(string txt, uint flags)
{
// do some stuff
}
}
This is my class and I use it this way
MyClass.Log.myFunction("some string", flags);
But constantly get that either MyClass is null or MyClass.Log is null when i use this class in other class functions.
What do I do wrong?
In addition to the question here is the error i get:
System.NullReferenceException: Object reference not set to an instance of an object.
at MyNamespace.MyClass..ctor()
at MyNamespace.MyClass.get_Log()
The code you showed looks good.
MyClass can't be null as it is a class. Log shouldn't be null either, your singleton implementation looks OK.
My guess is that the problem is that you are using the parameterless constructor of MyClass. I guess that myFunction somehow uses something that is only initialized in the constructor that takes the two parameters.
Actually, according to your stack trace the problem is inside the parameterless constructor. I guess you are trying to log something in there, like this : instance.Log(...);. That won't work, because at that point instance is still null. You should simply use Log(...) instead.

Prevent a Class having static instances of it created in C#

Is there anyway way to prevent a class having static instances of it created in C#. I don't think there is but it could be useful. E.g just some attribute to prevent it.
something like this
[NoStaticInstances]
public class MyClass {
}
so that
public static MyClass _myClass;
would cause an error?
There's no such thing as a "static instance" - there's only a static variable, which is assigned a value. And there's no way of preventing static variables of a particular type being declared, unless you make the type itself static, which will prevent any instances being created and any variables of that type from being declared.
Imagine if your desired feature did exist... how would you expect the following code to behave?
class Test
{
static object foo;
static void Main()
{
MyClass bar = new MyClass();
foo = bar;
}
}
Which line of that would cause an error, if any? If it's the assignment, imagine this instead:
class Test
{
static object foo;
static void Main()
{
MyClass bar = new MyClass();
object tmp = bar;
foo = tmp;
}
}
In short, I don't think you're going to be able to prevent static variables holding references to instances of your class. Out of interest, why do you want to?
What you can do is the following:
public class MyClass
{
public MyClass()
{
#if DEBUG // Only run in debug mode, because of performance.
StackTrace trace = new StackTrace();
var callingMethod = trace.GetFrames()[1].GetMethod();
if (callingMethod.IsStatic &&
callingMethod.Name == ".cctor")
{
throw new InvalidOperationException(
"You naughty boy!");
}
#endif
}
}
Static fields will 'normally' be created by static constructors. What the above code does is looking at the calling method to see if it is a static constructor and if that's the case, throw an exception.
Note however, that this check is quite fragile and smart users can easily work around this by refactoring the creation of this method to another method. In other words, I agree with every body else that there is no good way to do this.
Such a restriction would not make sense.
What if you write
static object something = new YourClass();
Not really, there is no language or compiler feature that supports this.
No, there's no way to dictate the scope or lifetime of object references in C#.

add generic Action<T> delegates to a list

Is it possible to add a generic delegate Action to a List collection?
I need some kind of simple messaging system for a Silverlight application.
UPDATE
The following is what i realy "want"
class SomeClass<T>
{
public T Data { get; set; }
// and more ....
}
class App
{
List<Action<SomeClass<T>>> _actions = new List<Action<SomeClass<T>>>();
void Add<T>( Action<SomeClass<T>> foo )
{
_actions.Add( foo );
}
}
Compiler:
The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)
initial code snipped
class SomeClassBase
{ }
class SomeClass<T> : SomeClassBase
{
public T Data { get; set; }
// and more ....
}
class App
{
List<Action<SomeClassBase>> _actions = new List<Action<SomeClassBase>>();
void Add<T>( Action<SomeClass<T>> foo )
where T : SomeClassBase
{
_actions.Add( foo );
}
}
The compiler complains - for the _actions.Add() line;
Argument 1: cannot convert from 'System.Action<test.SomeClass<T>>' to 'System.Action<test.SomeClassBase>'
The best overloaded method match for 'System.Collections.Generic.List<System.Action<test.SomeClassBase>>.Add(System.Action<test.SomeClassBase>)' has some invalid arguments
From the application side there is no need for the SomeClassBase class, yet it seems impossible to define a List of Action<SomeClass<T>> elements and the approach with the base-class works when using the class in the List, instead of the Action
Thanks,
jochen
EDIT: Okay, now I see what you're trying to do. I've left the old answer below for posterity :)
Unfortunately you can't express the relationship you want in C# generics, but as you can make sure you're the only one manipulating the collection, you can keep it safe yourself:
Try this:
class App
{
private readonly Dictionary<Type, object> delegateMap;
void Add<T>(Action<SomeClass<T>> foo)
{
object tmp;
if (!delegateMap.TryGetValue(typeof(T), out tmp))
{
tmp = new List<Action<SomeClass<T>>>();
delegateMap[typeof(t)] = tmp;
}
List<Action<SomeClass<T>> list = (List<Action<SomeClass<T>>) tmp;
list.Add(foo);
}
void InvokeActions<T>(SomeClass<T> item)
{
object tmp;
if (delegateMap.TryGetValue(typeof(T), out tmp))
{
List<Action<SomeClass<T>> list = (List<Action<SomeClass<T>>) tmp;
foreach (var action in list)
{
action(item);
}
}
}
}
Note that you could use the fact that delegates are multicast to just keep a Dictionary<Type, Delegate> and combine them together, but I'll leave that as an exercise for the reader :)
Old answer
It's failing for a good reason. Let's get rid of the generics (as they're irrelevant here) and think about a simpler case - fruit and bananas.
You're trying to add an Action<Banana> to a List<Action<Fruit>>. You can't do that - even with the generic variance of C# 4. Why? Because it's not safe. Consider this:
Action<Banana> peeler = banana => banana.Peel();
List<Action<Fruit>> fruitActions = new List<Action<Fruit>>();
fruitActions.Add(peeler); // Nope!
fruitActions[0].Invoke(new Strawberry());
Eek! Now we've got a banana peeler trying to peel a strawberry... what a mess!
Not that the other way round would be acceptable in C# 4:
Action<Fruit> eater = fruit => fruit.Eat();
List<Action<Banana>> bananaActions = new List<Action<Banana>>();
fruitActions.Add(eater); // Yes!
fruitActions[0].Invoke(new Banana());
Here we're adding an Action<Fruit> to a List<Action<Banana>> - that's acceptable, because anything you can do to an Action<Banana> is also valid for an Action<Fruit>.
Will this do what you want?
void Add<T>(Action<SomeClass<T>> foo)
where T : SomeClassBase
{
_actions.Add(x => foo((SomeClass<T>) x));
}
using System;
using System.Collections.Generic;
public delegate void MyDelegate<T>( T i );
public class DelegateList<T>
{
public void Add( MyDelegate<T> del ) {
imp.Add( del );
}
public void CallDelegates( T k ) {
foreach( MyDelegate<T> del in imp ) {
del( k );
}
}
private List<MyDelegate<T> > imp = new List<MyDelegate<T> >();
}
public class MainClass
{
static void Main() {
DelegateList<int> delegates = new DelegateList<int>();
delegates.Add( PrintInt );
delegates.CallDelegates( 42 );
}
static void PrintInt( int i ) {
Console.WriteLine( i );
}
}
Not sure if this is what you want. But try to change you Add method to:
void Add( Action<SomeClassBase> foo )
{
_actions.Add( foo );
}
Update
This will allow you to do something like this:
App app = new App();
Action<SomeClass<int>> action = null; // Initilize it...
app.Add((Action<SomeClassBase>)action);
If you look at the line
List<Action<SomeClass<T>>> _actions = new List<Action<SomeClass<T>>>();
The class T that you are referring to hasn't been declared anywhere. In SomeClass you have the right declaration for a generic class but in your App class you haven't told it what T is in this particular instance.
In summary I don't think this is doing what you want it to. With generics its easiest to imagine that when the code has been compiled there is no such thing as generics[0]. That during the compilation its just making all the classes you are using generically. This means there isn't really a concept of a list of generic classes since by the time you are using them the classes are of a given type and so can't be mixed.
I think the way it would need to work is using more definite class definitions but as Jon Skeet explained that doesn't really work either.
Perhaps the best idea is to take a few step backs and ask a question about what you are doing with this messaging system?
[0] Generics work differently in different languages but this is a good rough principle to work on I think...
I don't know if this is what you want exactly but if you want to have a method which invoke an action for each element in a list you can use an extension method like that :
public static class Extensions
{
public static void Action<T>(this IEnumerable<T> list, Action<T> action)
{
foreach (T element in list)
{
action.Invoke(element);
}
}
}
An exemple of call with myList of type IEnumerable<string>:
myList.Action(element => Console.WriteLine(element));
Maybe LINQ already implements an action in a List but if it's the case I don't know the syntax.

Categories

Resources