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 9 years ago.
Improve this question
I'm building a program in C# using Visual Studio 2010. And was wondering if there's a way to check it a variable exist.
So basically, my main.cs is calling several other files (file1.cs, file2.cs, file3.cs, etc). Each of this files are very similar but some are missing some variables.
For example, var v1 exists in file1.cs and file2.cs, but not file3.cs
In my main.cs, it's something like this.
string a = MyProgram.file1.v1;
string b = MyProgram.file2.v1;
string c = MyProgram.file3.v1; //will break here
I know the above code probably won't work at all, but that was the idea.
Is there a way I can check to see if v1 exists in file3.cs? Maybe something like this.
string c = VarExist(MyProgram.file3.v1) ? MyProgram.file3.v1 : "variable not exist";
I have tried to use try-catch, but the code won't even compile with that method.
EDIT
I know the variable doesn't exist, but is there a way for the program itself to check that?
In my main.cs, its looping through those file and applying the same operation. I want it to be able to do something like this:
foreach (file in files) //loop through file1.cs - file3.cs
{
if (file.v1 exist)
//do action1
if (file.v2 exist)
//do action2
if (file.v3 exist)
//do action3
//....
}
Right now the program won't even compile, I'll have to create v1 in file3.cs and set it to null. This was the temporary solution because on other parts/function of this program, it's requiring v1 to NOT be in file3.cs (and no I can't change this because it's what the previous develop set up and I don't know the code well enough to change it)
This is a fairly big solution so I'm sorry I can't really post actual code. Thank you all for the time I really appreciates it.
If you really need to do this this way, you could use reflection. Be aware, reflection is slow though. You will be able to then use a try/catch each time you attempt to get a property's value.
What you call "variables" should be properties or methods defined (or not) in each of your class modules (file1.cs, file2.cs, etc.)
Per the comments, you can add your items in a list like this:
var files = new List<userRule>()
{
MyProgram.file1,
MyProgram.file2,
MyProgram.file3
};
This can be done because the type of those "files" inherits from userRule.
Now you can iterate with:
foreach (file in files)
{
//something
}
For the check, do this:
foreach (file in files)
{
var property = file.GetType().GetProperty("v1");
if (property == null)
{
// it doesn't have the property
}
else
{
// it has the property
// read it:
var v1 = property.GetValue(file, null);
// write it:
property.SetValue(file, v1, null);
}
}
Related
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 1 year ago.
Improve this question
I have simple scenario where I started to repeat same code multiple times, so I decided to move it in a private method, depending on a if/else it's being edited and my variables that are listed below might overwrite it's value which is perfectly fine:
ProductResponse identificationResults = new ProductResponse(); // I understand this assignment gets overridden in private method below but that is goal
long? productIdentificationRecordId = null; // I understand this assignment gets overridden in private method below but that is goal
I'm invoking my method on a few places in a code that's reason why I created private method to avoid code repetition in same file:
await SetProductStatusAndPerformDbActions(productCompany, userId );
private async Task SetProductStatusAndPerformDbActions(Company productCompany, long userId, ProductType productType, ProductStatus status, long? productIdentificationRecordId, ProductResponse identificationResults, CancellationToken cancellationToken)
{
status = GetCompanyProductStatus(productCompany.Id, identificationResults);
productIdentificationRecordId = await PerformDbAction(status, productType, userId, cancellationToken); // underlined this code
identificationResults = await IdentifyCompanyProduct(productCompany, cancellationToken); // underlined this code
}
Visual Studio says 'Remove this useless assignment to a local variable
productIdentificationRecordId'
Visual Studio says 'Remove this useless assignment to a local variable
identificationResults'
I understand this assignments gets overridden in private method below but that is point of private method because I want to use for example productIdentificationRecordId and its new value right after I call this private method because goal of private method is to modify it and that is it..
I'm not using vars which might cause this warning so I don't know what to do here.
How this could be written to avoid this scenarios ?
Edit:
Added screenshot from the private method, variables are grayed as they are not used:
Because these parameters are not being passed by reference, setting them to any value will only change the value of the parameter variables local to your helper method: it will not impact the values that were passed in to those parameters.
Since you don't use the new values you're assigning to those parameters inside the method, Visual Studio is smart enough to recognize that setting values to them has no effect. It's warning you about that, which is good because in this case you might think your code is doing something that it's not really doing.
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 want to start new browser Chrome process.
In the class ChromeDriver have a method to do this.
And tried to initialize ChromeDriver like this:
ChromeDriver browser;
private void OpenBrowser()
{
browser = new ChromeDriver(Browsers.Chrome);
}
Problem is:
I start n process browser Chrome, and it runs only one browser, another process not run my code(although it initialized).
So, I tried to change code:
private void OpenBrowser()
{
var browser = new ChromeDriver(Browsers.Chrome);
}
It's working, but another method was using the browser. But I can't declare var browser out of a method.
It will return error like:
The contextual keyword 'var' may only appear within a local variable declaration or in script code
Updated:
I saw all answer and know var is ChromeDriver in my situation.
But when to run it, have the problem.
I will describe more information.
Suppose, I need to start 2 Chrome process. After initialized two Chrome process, I will go to URL with:
browser.GoToUrl(link);
So, I will know it working or not working.
At first, the case using ChromeDriver it still opens 2 Chrome process, but it was only working with the second process, the first process not working.
At second, the case using var keyword, it opens 2 Chrome process, and it was also working with two processes.
I'm not 100% clear on what you are trying to do but I can answer the question as asked:
var is just syntactic sugar to save having to write the full name of the type. As you can see from the error it can only be used with local variables.
What this means is that the following two lines are equivalent:
ChromeDriver browser = new ChromeDriver(Browsers.Chrome);
var browser = new ChromeDriver(Browsers.Chrome);
When compiled the compiler will see that browser is being set to an object of type ChromeDriver and thus act as if it was declared as ChromeDriver.
The main advantage of this is when working with ugly long variable names (often with generics) such as:
Dictionary<string, Dictionary<int, List<double>> myObject = new Dictionary<string, Dictionary<int, List<double>>();
This could be written more readably as:
var myObject = new Dictionary<string, Dictionary<int, List<double>>();
As an additional note it may be implicit in what I've said but to be explicit you need to have an assignment to use var. You couldn't for example do:
var myObject;
Because the compiler would complain that it can't work out the type of myObject (which is pretty obvious looking at that line of code!).
How about to return your reference from method?
private ChromeDriver OpenBrowser()
{
return new ChromeDriver(Browsers.Chrome);
}
Also, according to example ChromeDriver class implements IWebDriver interface so it's better to write like this:
private IWebDriver OpenChromeBrowser()
{
return new ChromeDriver(Browsers.Chrome);
}
In your another method (in same class, couse your method is private) you can use it like this:
var driver = OpenChromeBrowser();
When you declare a var variable .net needs to know what kind of var you are declaring, so you can use var when you have on the other side the type of var you are declaring.
var cool = new MySuperBrowserClass();
var lol = 69;
In both cases .net knows that on the other side there is a class of type MySuperBrowserClass or just an int.
In other words: if you want to declare a var, no matter the context, you have to clarify its type.
Perhaps (maybe is not the case because of other reasons!) you can change in your first code sample where you have:
ChromeBrowser browser;
doing something like:
var browser = new ChromeDriver(Browsers.Chrome);
var is a keyword that can only be used within the scope of a method. Using it within the scope of a class will throw an error.
If you could use it outside a method the result would be the same as your first example, as all it does is infer the type, which would mean it'd be the same as declaring it as ChromeDriver.
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 7 years ago.
Improve this question
I have an application that have several methods which checks for various errors on a computer. Right now i am calling the methods on load event of the form, but i kinda want to display what the program is doing by updating a label text for everything it does, like a progressbar. It should go from method to method in order.
And later i also want to check if everything has runned successfully. Should i look into Threading Tasks for this? Like starting a task for each method, stopping the task if it fails?
I would suggest to create the following classes:
WorkstationCheckBase - should be the base class for all checks.
WorkstationCheckRunner - gets a list of all checks and summarize
the result of each WorkstationCheckBase.
With that, you will encapsulate the checking from your UI and separete these concepts.
Now for you second question to show up on the UI some information (my assumation is that you use WinForm). For that you need a background task and update the UI frequently. You could use the Backgroundworker class for that.
Short answer: No, don't use threading-
Long answer: It depends!
When you get yourself into threading you start to face loads of other concurrency related problems, if all you want is to show a label of what is happening I would not suggest to use threads.
Since I have no code to look at I can only give you suggestions for how to solve your problem (without threading). The simplest way would be:
public void CheckErrors()
{
string errorText = string.Empty;
if (ErrorOneHasOccured(out errorText))
{
ErrorLabel += errorText;
}
errorText = string.Empty;
if (ErrorTwoHasOccured(out errorText))
{
ErrorLabel += errorText;
}
}
private bool ErrorOneHasOccured(out string errorText)
{
bool errorHasOccured = false;
errorText = string.Empty;
// DO error checking somehting
if (errorHasOccured)
{
errorText = "An error description";
return true;
}
return false;
}
Where :
ErrorLabel is the string property for the error text you want to display.
ErrorOneHasOccured is an example method for error checking, using the "Try" pattern.
I think this is the simplest way you can do it, but you can obviously engineer it further depending on what and why you need it.
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 8 years ago.
Improve this question
So I'm a little concerned about my error handling... Currently my execution path looks something like this:
Users.aspx -> App_Code/User.cs -> Data Layer/User.cs
So now when I try to update a user record, I put my Try/Catch block in the event handler and ensure that only the App_Code class interacts with the data layer. Exceptions that happen on the data layer, to my understanding, should bubble up to the event handler below.
In the data layer, I started off with this:
public void Update()
{
var product = (from p in db.products
where p.productid == id
select p).FirstOrDefault();
if (product != null)
{
// update the thing
}
}
More info on reddit.
After chatting with a friend, he recommended something like this:
public void Update()
{
int count = db.users.Count(u => u.userid == id);
if (count == 0) // no user found
{
throw new ValidationException(String.Format("User not found for id {0}.", id));
}
if (count > 1) // multiple users
{
throw new ValidationException(String.Format("Multiple users found for id {0}.", id));
}
var user = db.users.FirstOrDefault(u => u.userid == id);
// update the user record
}
Then I went onto IRC where they suggested I create my own Exceptions.
I can see the pros here, but it seems a bit unnecessary when my friend's option will work just fine.
Basically I'm just really confused as to how I should handle this... Obviously my initial option is insufficient, but it seems like creating my own exceptions might be complicating things too much.
So what should I do here?
Think of the other side here. As in, who is consuming that API. Whoever calls that method, they probably want to know that something went wrong. Exceptions provide that (return values could, too), while your initial approach doesn't.
Now consider that the consumer might want to distringuish the two cases »no users found« and »multiple users found«. In that case they're out of luck because you throw the same exception for both and have no way of distinguishing the two cases¹. In this case having distinct exception types for the different things that could have gone wrong can help.
But only if you actually need that capability in the caller. If you're using that method yourself, it's not part of a public API where you don't know how it might be used, and whether distinguishing those cases would be useful, I'd say don't bother.
I've used my own exception types rarely so far, and mostly when writing parsers for something where the exception type could hint at what exactly went wrong and you could use additional properties of the exception to generate a useful error message. In most other code I don't think I've ever done that.
¹ You could compare the exception message, but I'd advise never to do that. The message is for a user or developer to read. It could be translated into other languages (e.g. all exceptions from .NET are in your UI language, usually) which makes such an approach very brittle.
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