I'm a bit new to C# (coming from PHP) and I was a bit shocked that, by looping through a list I can't pass a reference to that varialbe, i.e. the following code is not valid:
foreach (ref string var in arr) {
var = "new value";
}
I researched a bit and I found a suggestion to create a "updatable enumerator" but I can't figure out how exactly I should do that. I followed an example and tried to add a setter for the Current for both the IEnumerator.Current method and my custom enumerator (PeopleEnum.Current), but, to be honest, that was blind guessing and didn't work. I'm pasting the whole code at pastebin, as it's quite long to paste here - custom enumerator attempt. In this code, trying to access the current element by
badClass baddie = new badClass(ref tmp.Current);
results in an expected error that "A property or indexer may not be passed as an out or ref parameter"
What I'm aiming to do in the end is something like this - iterate through a list of objects, generate a button for each of them and add an onclick event for that button which will open a new form, passing the reference for that object, so that its contents can be edited in that new form. I did all this, but passing the object as a reference, instead of read-only data, is killing me. I would appreciate any answers, links where I can read about updatable enumerators or ideas.
First of all - without wanting to blame you - I would say: If you learn a new language, learn the new language! And don't try to develop PHP using C#. If computer languages would all be the same, we would not have so much of them. ;-)
I don't see exactly how your example is related to the actual job you want to do, but you shoudl probably learn about events, delegates and LINQ first. Might something like this help:
foreach (Obj obj in yourBaseObjects) {
Obj localObj = obj; // See Dans comment!!!
Button button = new Button(); // however you create your buttons
button.Click += {
// do something with obj
Console.WriteLine(localObj);
}
}
Yes, that works in C# and each event handler will be using the correct object. If it does not fit your needs, you have to provide more details.
Why you are using foreach loop. Use for loop. I dont know the exact code/syntax but something like that:
int sizeOfArray=objectArray.size();
for(int i=0;i<sizeOfArray;i++)
{
obj=objectArray[i];
// use obj whatever you wany
}
It sounds like you're not trying to pass a reference to the Object (the Object is already a reference type), but rather a reference to the Object's location in the array, correct? This latter is not directly possible in .NET, due to the way it manages memory and references. You can accomplish something like it using a wrapper class (no error handling, but this is the basic idea):
public sealed class ListReference<T>
{
private readonly IList<T> _list;
private readonly int _index;
public ListReference(IList<T> list, int index)
{
_list = list;
_index = index;
}
public T Value
{
get { return _list[_index]; }
set { _list[_index] = value; }
}
}
You can now construct this and pass it along, with all the associated complexity risks that come with passing around multiple references to an array. It would be better to change the design to avoid this, if possible, but it is possible to accomplish what you're after.
Related
So, C# has a wonderful feature where you can add actual variables to lists, but that is unhelpful for me right now as I want the value of said variable.
public List<List<float?>> distMatrix = new List<List<float?>>();
public List<List<float>> routeMatrix = new List<List<float>>();
public List<List<List<float?>>> distMatrixHistory = new List<List<List<float?>>();
public List<List<List<float>>> routeMatrixHistory = new List<List<List<float>>();
This is where I am defining my variables.
distMatrixHistory.Add(distMatrix);
routeMatrixHistory.Add(routeMatrix);
And this is the piece of code I have that adds those matrices to the matrix history list. The issue is that I loop and change the value of these matrices, but I don't want the value of the elements in the matrixhistory lists to change too.
I know that, theoretically, I can just do this manually. I know that I can probably program a small function that would cycle through and add each value separately. But this seems like something that c# should have inbuilt functions (or libraries) to deal with, even if I have not found anything when looking into it.
Side note: If anyone wants a bit more context, this is a small program
that runs Floyd's Algorithm, so I cycle every step and change my
distance and my route matrix, and my little winforms app should
theoretically be able to display any step requested.
Create a copy using the List<T>(IEnumerable<T>) constructor:
List<List<float>> copy = routeMatrix.Select(list => new List<float>(list)).ToList();
routeMatrixHistory.Add(copy);
Then you can safely change values in your routeMatrix without affecting the history.
You could wrap this in an extension method if it needs to be reused:
static class Extensions
{
static List<List<T>> Copy<T>(this List<List<T>> list)
{
return list.Select(l => new List<T>(l)).ToList();
}
}
Example usage:
distMatrixHistory.Add(distMatrix.Copy());
routeMatrixHistory.Add(routeMatrix.Copy());
I've been finding myself doing this pattern, for large pre-existing objects we want to modify slightly to pass down to another call, but don't want to copy but don't want the caller to see the change:
ResultType f(T x, TLarge config) {
var oldVal = config.blah; // 1st line of boilerplate
config.blah = "New Value"; // 2nd line of boilerplate
try {
return g(config);
}
finally
{
config.blah = oldVal; // 3rd line of boilerplate
}
}
This gets a bit messy particularly when there's more than one variable to change.
Is there a nice way to wrap this up into a pattern? I tried using using and sticking a reference as a member to an IDisposable struct and resetting on close but that didn't work as references can't be members.
A lot of the types I'm temporarily modifying are strings and ints so this needs to work with value types.
Rookie question:
I have been experiencing a minor bug in my mvc2 application. I was able to trace it back to this code:
List<Stream2FieldTypes> Stream2FieldTypes = new List<Stream2FieldTypes>();
foreach (var item in stream.Stream2FieldTypes)
{
Stream2FieldTypes.Add(item);
}
The problem that I am experiencing is that when I instatiate the new list, it has a count of one. I'm thinking that this is probably due to my using the constructor. So I tried this:
List<Stream2FieldTypes> Stream2FieldTypes;
foreach (var item in stream.Stream2FieldTypes)
{
Stream2FieldTypes.Add(item);
}
But, of course this will not compile because of an error on Stream2FieldTypes.Add(item);. Is there a way that I can create a List<Stream2FieldTypes> and make sure that the count is zero?
The problem that I am experiencing is that when I instatiate the new list, it has a length of one
No, that's totally impossible. Your problem is somewhere else and unrelated to the number of elements of a newly instantiated list.
List<Stream2FieldTypes> Stream2FieldTypes = new List<Stream2FieldTypes>();
Stream2FieldTypes.Count will be 0 at this point no matter what you do (assuming of course single threaded sequential access but List<T> is not thread-safe anyways so it's a safe assumption :-)).
The constructor:
List<Stream2FieldTypes> Stream2FieldTypes = new List<Stream2FieldTypes>(0);
will create a list with a default capacity of zero.
ETA: Though, looking at Reflector, it seems that the static and default constructors also create the list with a default capacity of zero. So your code as it stands should create a list with no elements and no reserved capacity. Should be more performant than the explicit constructor.
Also, if you use IEnumerable, you can do some nice tricks:
public void processTheList(List<string> someList = null)
{
// Instead of special-casing null, make your code cleaner
var list = someList ?? Enumerable.Empty<string>();
// Now we can always assume list is a valid IEnumerable
foreach(string item in list) { /* ... */ }
}
This seems like a multi-threading issue, are you sure that this is a thread safe method and another thread didn't already add an item to this list?
We need to see this method in a bigger context of your code.
It looks to me that you have your constructor set up incorrectly. I may be wrong but instead of List<Stream2FieldTypes> Stream2FieldTypes = new List<Stream2FieldTypes>(); you should be naming it different than the type you are using? List<Stream2FieldTypes> SomethingElse = new List<Stream2FieldTypes>();
Try that it should work.
I have various classes for handling form data and querying a database. I need some advice on reducing the amount of code I write from site to site.
The following code is for handling a form posted via ajax to the server. It simply instantiates a Form class, validates the data and processes any errors:
public static string submit(Dictionary<string, string> d){
Form f = new Form("myform");
if (!f.validate(d)){
return f.errors.toJSON();
}
//process form...
}
Is there a way to reduce this down to 1 line as follows:
if (!Form.validate("myform", d)){ return Form.errors.toJSON(); }
Let's break that down into two questions.
1) Can I write the existing logic all in one statement?
The local variable has to be declared in its own statement, but the initializer doesn't have to be there. It's prefectly legal to say:
Form f;
if (!(f=new Form("myform")).validate(d))return f.errors.toJSON();
Why you would want to is beyond me; doing so is ugly, hard to debug, hard to understand, and hard to maintain. But it's perfectly legal.
2) Can I make this instance method into a static method?
Probably not directly. Suppose you had two callers validating stuff on two different threads, both calling the static Form.Validate method, and both producing errors. Now you have a race. One of them is going to win and fill in Form.Errors. And now you have two threads reporting the same set of errors, but the errors are wrong for one of them.
The better way to make this into a static method is to make the whole thing into a static method that has the desired semantics, as in plinth's answer.
Errors errors = Validator.Validate(d);
if (errors != null) return errors.toJSON();
Now the code is very clear, and the implementation of Validate is straightforward. Create a form, call the validator, either return null or the errors.
I would suggest that you don't need advice on reducing the amount of code you write. Rather, get advice on how to make the code read more like the meaning it intends to represent. Sometimes that means writing slightly more code, but that code is clear and easy to understand.
I would move all common validation logic to a superclass.
I think the main problem of your code is not that is long, but that you're repeating that in many places, either if you manage to make it a one-liner, it would not be DRY.
Take a look at the Template Method pattern, it might help here (The abstract class with the validation would be the Template and your specific 'actions' would be the subclasses).
Of course you could write this:
public static string FormValidate(Dictionary<string, string> d)
{
Form f = new Form("myform");
if (!f.validate(d))
return f.errors.ToJSON();
return null;
}
then your submit can be:
public static string submit(Dictionary<string, string> d)
{
if ((string errs = FormValidate(d))!= null) { return errs; }
// process form
}
That cuts down your code and doesn't hurt readability much at all.
If you really, really wanted to, you could store the error text in a thread-local property.
Does C# have a "ThreadLocal" analog (for data members) to the "ThreadStatic" attribute?
Question
I'm writing some code that needs to be able to get the values of the parameters from the method that called into the class. I know how to get all the way to the ParameterInfo[] array, but I don't know how to then get the values. Is this even possible?
If it is, I think it has something to do with using the MethodBody property from the MethodInfo object, which allows you to inspect the IL stream, including properties, but I don't know how to do it, and I haven't found applicable code on Google.
Code
// Finds calling method from class that called into this one
public class SomeClass
{
public static void FindMethod()
{
for (int i = 1; i < frameCount; i++)
{
var frame = new StackFrame(i);
var methodInfo = frame.GetMethod();
if (methodInfo.DeclaringType != this.GetType())
{
string methodName = frame.GetMethod().Name;
var paramInfos = methodInfo.GetParameters();
// Now what?? How do I get the values from the paramInfos
break;
}
else if (i == frameCount - 1)
{
throw new TransportException("Couldn't find method name");
}
}
}
}
You cannot do it without introspecting the stack yourself (and this is fragile since many optimizations may mean the stack frame is not what you expect, or even that the parameter passed is not in fact what the method signature would suggest (it is perfectly possible for an optimizing JIT compiler to spot that you are only using a sub field of an object/struct and pass that instead).
The ParameterInfo simply tells you the signature of the method as compiled, not the values that were passed.
The only realistic way to achieve this automatically is via code injection (via something like AOP) to create the data and do what you want with it based on analysing the IL.
This is generally not a good idea, if you need to debug something use a debugger, if you need to log something be explicit about what you are logging.
To be clear simple reflective techniques cannot achieve what you desire with full generality
Jonathan Keljo at Microsoft says, in this news group post, :
Unfortunately, the only easy way to get argument information from a
callstack today is with a debugger. If you're trying to do this as part of
error logging in an application and you plan to send the error log back to
your support department, we're hoping to have you use minidumps for that
purpose in the future. (Today, using a minidump with managed code is a
little problematic as it does not include enough information to even get a
stack trace by default. A minidump with heap is better, but not so "mini"
if you know what I mean.)
A purist would say that allowing people to write code that can get
arguments from functions elsewhere on the callstack would encourage them to
break encapsulation and create code that's very fragile in the face of
change. (Your scenario does not have this particular problem, but I've
heard other requests for this feature that would. Anyway most of those
requests can be solved in other ways, like using thread stores.) However,
more importantly there would be security implications of this--applications
that allow plugins would be at risk of those plugins scraping the stack for
sensitive information. We could certainly mark the function as requiring
full-trust, but that would make it unusable for pretty much every scenario
I've heard of.
Jonathan
So... I guess the short answer is "I can't." That sucks.
Yes, you can do this.
What you need to do is use an IL disassembler (which is achievable within the System.Reflection.Emit namespace) to find the Operand that contains the parameter value you're looking for.
Start with this SO question: C# reflection and finding all references
Then use the class mentioned in the answers (from Mono.Reflection) to do your inspection. Something like this:
var instructions = method.GetInstructions();
foreach (var instruction in instructions)
{
var methodInfo = instruction.Operand as MethodInfo;
if(methodInfo == null)
{
continue;
}
if (instruction.OpCode.Name.Equals("call") && methodInfo.Name.Equals("YourMethodHere"))
{
var value = (CastToMyType)instruction.Previous.Operand;
// Now you have the value...
}
}
You can't do it with either StackFrame or StackTrace. You can, however, employ some interception framework (such as AOP stuff from Spring.NET) so that you can get hold of parameter values.
See here:
Can you get a list of variables on the stack in C#?
I don't think it's possbile, based on all the comments on my answer there. The PropertyInfo class does have a GetValue method, but that requires you to have an actual object of which you want to get the value from.
Not sure if this counts as a solution, but worked for a specific case that i had,
i wanted to log each time a float was modified with minimal code changes,
Reading the file on the stack trace line to figure out the params
public static Score operator +(Score x,float y) {
var st = new StackTrace(true);
var sf = st.GetFrame(1);
string paramName = File.ReadLines(sf.GetFileName()).ElementAtOrDefault(sf.GetFileLineNumber()-1).Split(new[] { "+=" }, StringSplitOptions.None)[1];
x.DebugString += (paramName+" "+y);
x.DebugString += System.Environment.NewLine;
x.val += y;
return x;
}
void Main(){
Score score = new Score();
float firstScore = 2;
float secondScore = -13;
score+=firstScore;
score+=secondScore;
Console.WriteLine(score.DebugString);
}
Output :
firstscore 2
secondScore -13