I have the following recursive function that is used to search down a hierarchical tree and remove found objects from a list:
private List<Tag> RemoveInvalidTags(Device device, List<Tag> tags)
{
var childDevices = device.ChildDevices.Select(c => c.ChildDevice);
foreach (var child in childDevices)
{
tags.Remove(child.Tag);
RemoveInvalidTags(child, tags);
}
return tags;
}
What I am expecting this to do is remove all child device tags at this level from the tags list, call the function recursively for your children, then return that list up to the previous level.
Will this pass the tags list by reference and modify the original passed list? Or should I be doing something along the lines of
validTags = CollectValidTags(child, tags);
and adding up all the returned lists?
Will this pass the tags list by reference
No. The list object is passed "by value" (but see next). (ref or out is required to "pass by reference" in C#, but that is not being done here, nor does it need to be.)
and modify the original passed list?
Yes. This is because the list object is passed. And that list object is mutated. Passing a reference type (anything defined with class) never implicitly makes a copy/clone/duplicate. An object is what it is.
Now, back to "pass by value": the "value passed" is the value of the "reference" (internal, no need to concern with this): this calling strategy is better known as Call/Pass By Object Sharing in a langauge like C#. The same object is shared (just as if it were assigned to two different variables). (Value types -- a struct -- are different in that they (often) are copied/duplicated on the stack, but a List<T> is a class.)
Or should I be doing something along the lines of
It depends upon the desired semantics. Is the caller expecting the side-effects directly or indirectly? Can the mutation side-effect lead to unexpected scenarios? Make sure to document it either way. (I prefer the way that guarantees the initial object is not mutated.)
Hope that clears some things up.
Happy coding.
In your code you are modifying the items in your tags parameter and passing back the modified list as your result. You want to avoid modifying lists in this way - especially inside loops where it can cause you grief in many situations.
I have a LINQ-based alternative for you.
If I understand the intent of your code you want to do something like this:
Func<Device, IEnumerable<Device>> flatten = null;
flatten = d =>
{
return (new [] { d }).Concat(
from c in d.ChildDevices
from f in flatten(c)
select f);
};
var collectedValidTags = flatten(device).Select(d => d.Tag);
var result = tags.Except(collectedValidTags).ToList();
This approach doesn't pass your list of tags around so there is no chance of modifying your original list.
Does this help?
Short answer - your code will do what you want.
Long answer - you should read descriptions of what the ref keyword does. I would suggest you read as many descriptions as possible; there are many different ways to articulate it ("I like to think of it as... ") and some will work for you whilst others won't. If you read many descriptions (from people who understand it) then some kind of understanding should gel for you.
Here's a list to get you started:
Use of 'ref' keyword in C# (my answer)
C# ref keyword usage
Passing by ref?
Example of practical of "ref" use
Related
I consider this as a continuation of what I've learned from my two previous threads. Instead of Javascript I will be using pure C#.
I have a class with 3 parameters in it, and I am creating a variable which is a result of deserialization to class type
var param = js.Deserialize<ClassName>(jqData.Params);
Based on what I've learned from my first thread, it stores values based on inputs I've made within 3 textboxes that I have.
For our purposes, let's assume I only placed input in a second textbox out of three, so the values would be null, "abc", null.
Now, I got some very good suggestions from my second post, which I want to implement.
I want to create an array of objects, WITHOUT initializing, since those objects already hold values, reduce array down to 1 element based on criteria from that excellent post, and then proceed with my validation logic.
However, I am struggling with declaring array part. From what I saw here in SO, most of threads are talking about declaring and initializing those elements. I don't need it.
What I need is to declare an array, which would have class elements in it, something like array = [param.elem1, param.elem2, param.elem3], and when I run a code, it will return [null, "abc", null].
Can you please point me in the right direction on how to properly declare such array?
Your idea was close to how this can be handled. Just change your array = [param.elem1, param.elem2, param.elem3] to:
var myArray = new object[] { param.elem1, param.elem2, param.elem3 };
If you know the type of param.elem1/2/3, you can use the specific type (e.g. string[] instead of object[]).
I am wondering about whether or not creating a list of an anonymous type is the best way to effectively create a list of multiple types as well as its effect on general performance and efficiency. Mainly I just want to know if there is a more standard way of doing List?
Situation
I every now and then find myself with a need to create a list that has multiple values each of a different type, List. Normally i would just resolve this with a Dictionary, but then there are the cases where i don't care about duplicated key values or need a 3rd (or rarely 4th) value. Usually this is for temporary list that just track something contained in a method like logging thrown errors and an associated value so that at the end of the method i can string together the messages for a log file or something.
What i have so far is this:
var list = new[] { new { RowNumber = 1, Message = "" } }.ToList();
list.Clear();//clears out the example used to create the anonymous type
list.Add(new { RowNumber = 10, Message = "bla bla" }); //adding to the list
I am debating on doing something like an extension or something to make this easier, but if the performance sucks or there is a better way, i would like to know.
I prefer to make a class. The IL just makes an anonymous class in native that gets called the same way as a normal class, so there is no performance hit associated with it. If you ever debug anonymous types, you'll notice the name has a long name like AnonymousTypes.Program+f__1
Creating a class improves the readability of your code IMO.
public class RowMessage
{
public int RowNumber { get; set; }
public string Message { get; set; }
}
You can also use Tuples, but even this is still unclear:
public void MyMethod()
{
Tuple<int, string> myTuple = new Tuple<int, string>(1, "hi");
List<Tuple<int, string>> myTupList = new List<Tuple<int, string>>();
myTupList.Add(myTuple);
}
I just experimented a little. Here's what I found:
Anonymous types are as good as anything else. I can't really say "anything," since I didn't try everything. But I can tell you that they're as good as Tuple<> and concrete types. This is logical, because underneath the covers, the compiler actually builds types for anonymous types. In essence, at runtime, they are just concrete types.
Your ToList call is redundant. This part's important. It's not super relevant to your immediate question, but looking at your example, you do new [] { ... }.ToList(). This forces a loop through the array after it's created. You'd be much better off using list initialization: new List<dynamic> { ... };. That's what I used in my examples.
I ran tests 10,000 times each for:
Anonymous type with array initializer (00:00:00.0050338 total)
Anonymous type with list initializer (00:00:00.0035599 total)
Tuple with list initializer (00:00:00.0025857 total)
Concrete type with list initializer (00:00:00.0041538 total)
Running them again would just mix it up. The only consistent result was that arrays were, unsurprisingly, slower than going directly to a list.
If you're going to make an extension method, you'll probably want to go with one of the latter two options. Anonymous types don't travel well outside of their scope, as I'm sure you know. The choice is yours between concrete types and tuples. I'd go with concrete if you're using it a lot and/or outside of the original method, and a tuple if it just needs to exist somewhere. That's really a design choice that I can't make for you.
Since you are talking about enriching Exceptioninformation it is worth to mention that the Exceptionclass implements a property called Data which is of type IDictionary and can be used to append additional information.
try
{
throw new FileNotFoundException{ Data ={ { "TEST", "Hello World" } } };
}
catch (Exception e)
{
Console.WriteLine(e.Data["TEST"]);
...
e.Data.Add("Whatever", DateTime.Now);
}
If you find yourself adding the same information lots of times, consider some HelperMethods that add certain information to a giving exception. This could also take care for duplicated keys which use some sort of numeric postfix that increments like fileName_1 and so on, you get the idea.
You can also create a standartized method of outputting those Information you provided yourself.
If you want a more Complex approach you can just simply use List but make the consumer of this list handle each kind of type. Which is basically the idea behind the DebuggerTypeProxy-Atrribute
So you can for example use some pattern like this:
foreach(var typeGroup in additionalInformation.GroupBy(item => item.GetType())
{
ITypedLogHandler handler = GetHandlerFor(typeGroup.Key);
handler.WriteLog(typeGroup);
}
In general the only reason I can think of this whole idea to beeing valid is some convenient debuggint/loggin approach. Anything else should really use strong typing.
I'm trying to gather the switch section label constants from a SwitchStatement with Roslyn. But while I can see in the Syntax Visualizer that the CaseSwitchLabelSyntax has a Value property with the corresponding constant and the declared symbol (SourceLabelSymbol) has a SwitchCaseLabelConstant property, I cannot seem to get that information from what I have in my code.
// SwitchStatementSyntax node;
// SemanticModel model;
foreach (var section in node.Sections) {
foreach (var label in section.Labels) {
var labelSymbol = model.GetDeclaredSymbol(label);
// Here I'm stuck
}
}
I could probably look whether the SwitchLabelSyntax is a CaseSwitchLabelSyntax or a DefaultSwitchLabelSyntax and cast accordingly. SourceLabelSymbol is actually internal, so I cannot access its properties. model.GetConstantValue(label) returns null.
But given that Roslyn always hands out interfaces I believe that there's a reason for that and wildly casting around feels a bit hacky to me. Is there a better option?
Note: I'm doing this to translate C# syntax into another language. Technically, first into a separate AST that is then converted to text again. Above code is from within a CSharpSyntaxWalker and I could probably just store my partially converted switch statement away, continue visiting its descendants and build it up piecewise.
But that means having more state, building statements in half a dozen distinct locations which leads to hard-to-read and -follow code. I'd rather avoid it here, if possible.
Closest from API is semanticModel.GetConstantValue method, but still you need to pass Value node to it like this:
section.Labels
.OfType<CaseSwitchLabelSyntax>()
.Select(l => semanticModel.GetConstantValue(l.Value))
.ToArray()
As you can see filtering out CaseSwitchLabelSyntax is required anyway.
I know that the method is returning List<string> at the moment. But in some (which occur quite frequently in our application) scenarios, it returns List having only one string.
So eventually it would return either string or List<string>.
Since it's unpredictable what it'll return at run time, at present it's return type is kept as object.
What alternative approach could be used to avoid method returning object?
EDIT:
I would like to have answer to the question What alternative approach could be used to avoid method returning object? ; without considering the scenario I described. List is enough here.
why return a string? a List<string> with a single string in it is perfectly well defined... use that! An ambiguous API is silly here.
Another option might be IEnumerable<string>, but... meh, just return the list with a single string!
Return a List that contains one or more string elements, and process the list as a list regardless of the number of elements it contains.
There is no problem to have a List with one and more and even with no string(empty list).
Why you want to have string when there is only one element in the List.
Just keep the API more clear.
I dont see the the problem of returning List<string> even the List contain only one element. But if you really want your method to behave differently with one string value, you could do
public List<string> GetStrList(out string val)
{
//set str = string.Empty; when value is more than one
//set str = whateverstring when value is only one
}
Hmm, does this method perhaps call 2 different methods inside its body, one returning a string and one returning a List<string>? If so, maybe you could change your method to return an IEnumerable<string>, and change the return GetSingleString(); statement to yield returnGetSingleString();
Or you could add it to a list with a single element and return the list, like some of the other answers suggest here
Let's say I have a list:
List<object> list = new List();
list.Add(object1);
list.Add(object2);
object foo = list[0];
How do I make a call to list to replace list[0] such that foo will automatically point to the newly replaced object?
I know this line won't do the trick as foo will continue pointing to the old value of list[0]...
list[0] = object3;
Thanks!
It's not possible in my opinion. You need an additonal level of indirection which you have to implement yourself.
You could use a delegate/ anonymous lambda that fetches list[0]:
Func<object> foo = () => list[0];
Of course that changes the syntax slightly since it's now foo() instead of foo but it has the effect that you can fetch the value of list[0] at any time later and it always gets the current value.
What you really want to be able to do is to override the assignment operator but that's not possible in C#. The closest you'll get is to create a class that behaves a bit like Nullable<T> having a .Value property on it and assign to that .Value property instead of overwriting the object itself in the list.
You can use the fixed keyword but only in unsafe code. But i'm not sure what your attempting to do so it may not suite your needs if you need this level of control c++ cli would be a better choice.
Unsafe pointers are one possibility: http://msdn.microsoft.com/en-us/library/y31yhkeb(v=vs.80).aspx
For "safe" code, you can do something like store your value in an array of length 1, and then only store references to the array and always access the value by array[0], but this is a bit of a hack and there is probably a better way to do what you want to accomplish.