C# Variable Scoping - c#

I'm new to C#, having written a little in a CMS, but my background is mostly JavaScript related. That said, I am working in the "Scripting" client in OpenText Capture Center. When executing the code below I get the error "The Name 'srfOnly' does not exist in the current context"
If I move the variable declarations to within the function, I get the same error, If I move them to them to global I get the same error but on a different line number.
How can I access the variables srfOnly and otherDocs throughout the code?
//Parameters:
//DataPool data
//ITrace trace
// Checking if condition is fulfilled.
if (checkDocuments(data))
{
// Getting batch field named 'cc_SkipValidation'.
// Setting new value.
DOKuStar.Data.Xml.Bool skipValidationField = data.RootNode.Fields["cc_SkipValidation"] as DOKuStar.Data.Xml.Bool;
bool srfOnly = false;
bool otherDocs = false;
if(otherDocs == true)
{
skipValidationField.SetValue(false);
}
if(srfOnly == true && otherDocs == false)
{
skipValidationField.SetValue(true);
skipValidationField.State = DataState.Ok;
}
}
// !!! Closing bracket is neccessary !!!
}
// ------------------ Functions
public bool checkDocuments(DataPool dataPool)
{
foreach (Document doc in dataPool.RootNode.Documents)
{
if (doc.Name == "ServiceRequestForm")
{
srfOnly = true;
}
else if (doc.Name != "ServiceRequestForm")
{
otherDocs = true;
}
}
trace.WriteInfo("Trace info for Validation of srfOnly = " + srfOnly);
trace.WriteInfo("Trace info for Validation of otherDocs = " + otherDocs);
// !!! No closing bracket needed !!!

Variables are limited in scope by where they exist in your code. If you declare a variable within an if{} block, the variable only exists inside that block. If you declare a variable inside of a class but not within a class method, the variable is accessible to every method in the class. If you want a variable to be accessible to every class with in a project, you would normally declare it in a public static class.
For example...
public static class GlobalClass
{
public static string myGlobal="";
}
class myClass
{
string myClassVariable = "";
private void method()
{
//myGlobal is accessible using this
GlobalClass.myGlobal ="some value";
//myClassVariable is accessible here
myClassVariable = "somevalue";
if(condition)
{
//myClassVariable is also accessible here
myClassVariable = "somevalue";
string ifBlockVariable = "";
}
//ifBlockVariable is not accessible here
}
}

A variable is only accessible within the current block (and the blocks within that block). If you want to access the srfOnly variable within the checkDocuments method you can pass it as a parameter:
public bool checkDocuments(DataPool dataPool, bool srfOnly)
If you want the variable to be accessible from anywhere in the class, you can declare it as a a property of the class or an instance variable as following:
private bool _srfOnly;

Related

How to replicate a global variable in C#?

I have a variable in one loop in C# that cannot be recognized in the other one, and I am aware that it is not possible to create a true global variable in C#, however I wonder if one can mimic one. Some of my code is this:
foreach (string line in lines)
{
if (line.Contains("write"))
{
var tempctr = line.Replace("(", "");
var tempctr2 = line.Replace(")", "");
var ctr = tempctr2.Remove(0, 6);
Console.Write(ctr);
}
else if (line.Contains("sayinput"))
{
Console.Write(usrinput);
}
else if (line.Contains("inputget"))
{
var tempctr = line.Replace("(", "");
var tempctr2 = line.Replace(")", "");
var ctr = tempctr2.Remove(0, 9);
Console.Write(ctr);
string usrinput = Console.ReadLine();
}
}
The code reads from a text file and runs a certain command based on what is in the text. My intention is for it to create a variable with inputget and spit it back out with sayinput.
And the first usrinput reference is an error, since the variable is declared outside of the loop.
You don't need a global variable here. Just declare usrinput outside your loop, like so:
string usrinput = "";
foreach (string line in lines)
{
if (line.Contains("write"))
{
//...
}
else if (line.Contains("sayinput"))
{
Console.Write(usrinput);
}
else if (line.Contains("inputget"))
{
// ...
usrinput = Console.ReadLine();
}
}
it is not possible to create a true global variable in C#,
Static variable on a class. Done. Global in the definition of any global variable (i.e. you must be in the same process). And standard C#.

Roslyn Check If Field Declaration has been assigned to

I'm writing an app which converts keys to use resources from a RESX File. This code was working with local variables before:
public static void AnalyzeConstDeclaration(SyntaxNodeAnalysisContext context)
{
var fieldDeclaration = (FieldDeclarationSyntax)context.Node;
if (false == IsValidFieldDeclaration(context, fieldDeclaration))
{
return;
}
var firstVariable = fieldDeclaration.Declaration.Variables.FirstOrDefault();
var dataFlowAnalysis = context.SemanticModel.AnalyzeDataFlow(firstVariable);
var variableSymbol = context.SemanticModel.GetDeclaredSymbol(firstVariable);
if (dataFlowAnalysis.WrittenOutside.Contains(variableSymbol))
{
return;
}
var firstSymbol = context.SemanticModel.GetDeclaredSymbol(firstVariable);
context.ReportDiagnostic(Diagnostic.Create(Rule, context.Node.GetLocation(), firstSymbol.Name));
}
However when I try to get the dataFlowAnalysis I receive an error:
Additional information: statementOrExpression is not a StatementSyntax or an ExpressionSyntax.
How can Ideally just need to see if anyone has written to this variable outside of the declaration.
DataFlow works by analyzing order of execution within a single method.
It doesn't make sense for class-level fields.
Instead, you should use a simple syntax visitor (or SymbolFinder) to search the entire class for assignments to the field.
You'll probably also want to check whether it's ever passed as a ref parameter.

C# Error: The contextual keyword 'var' may only appear within a local variable declaration

I have written the following function to create an axWindowsMediaPlayer playlist:
WMPLib.IWMPPlaylist p2 = axWindowsMediaPlayer.playlistCollection.newPlaylist("Playlist 1");
private void CreatePlaylist(string _currentId)
{
string selectedElementPageTypeValue = MainContentAreaBl.GetSelectedElementPageTypeValue(_currentId);
var selectedElementJumpToValue = MainContentAreaBl.GetSelectedElementValue(_currentId, "jumpTo");
if (selectedElementJumpToValue != null)
{
_currentId = selectedElementJumpToValue;
if (_currentId != null && _currentId != "menu" && selectedElementPageTypeValue == "video")
{
var playerFile = Path.Combine(Common.ContentFolderPath, MainContentAreaBl.GetSelectedElementDataPathValue(_currentId));
p2.appendItem(axWindowsMediaPlayer.newMedia(playerFile));
axWindowsMediaPlayer.currentPlaylist = p2;
CreatePlaylist(_currentId);
}
axWindowsMediaPlayer.Ctlcontrols.play();
}
}
Here var p2 is declared at class level. When I compiled my application, i received the following error message:
The contextual keyword 'var' may only appear within a local variable declaration
However, I cannot put var p2 = axWindowsMediaPlayer.playlistCollection.newPlaylist("Playlist 1"); inside the recursive function as it will create new playlist on each iteration.
How do I access p2 in my function?
Edit 1: I am seeing this in Output Window
COM Reference 'WMPLib' is the interop assembly for ActiveX control 'AxWMPLib' but was marked to be linked by the compiler with the /link flag. This COM reference will be treated as a reference and will not be linked.
Also, now it shows the following error on axWindowsMediaplayer:
A field initializer cannot reference the non-static field, method or property
Does this information has to do anything with the Error that I am seeing? How do go about resolving this?
You will have to declare it with the right type instead of using var:
AxWMPLib.IWMPPlaylist p2 = axWindowsMediaPlayer.playlistCollection.newPlaylist("Playlist 1");
var is only allowed on local variables, not on fields, and that's what the error message tells you. The error message does not mean that the field is declared in the wrong place, you just used the wrong syntax for the field type.
The MSDN says:
To correct this error
If the variable belongs at class scope, give it an explicit type.
Otherwise move it inside the method where it will be used.
So you can give the correct type while declaring the type of your variable like
IWMPPlaylist p2 = axWindowsMediaPlayer.playlistCollection.newPlaylist("Playlist 1");
or else you can move the variable inside the method where it is going to be used. In your case, you can move it inside the CreatePlaylist method.
Initializing the playlist in the Constructor and passing the playlist as arguments did the trick as answered by #thumbnumkeys (now removed). Here is the code that worked for me:
namespace ABC
{
public partial class MainContentArea : Form
{
private string _currentId;
public MainContentArea(string topicId, Menu menu)
{
InitializeComponent();
_currentId = topicId;
_menu = menu;
WMPLib.IWMPPlaylist p2 = axWindowsMediaPlayer.playlistCollection.newPlaylist("Playlist 1");
CreatePlaylist(_currentId, p2);
}
private void CreatePlaylist(string _currentId, WMPLib.IWMPPlaylist p2)
{
var selectedElementJumpToValue = MainContentAreaBl.GetSelectedElementValue(_currentId, "jumpTo");
string selectedElementPageTypeValue = MainContentAreaBl.GetSelectedElementPageTypeValue(selectedElementJumpToValue);
if (selectedElementJumpToValue != null)
{
_currentId = selectedElementJumpToValue;
if (_currentId != null && _currentId != "menu" && selectedElementPageTypeValue == "video")
{
var playerFile = Path.Combine(Common.ContentFolderPath, MainContentAreaBl.GetSelectedElementDataPathValue(_currentId));
p2.appendItem(axWindowsMediaPlayer.newMedia(playerFile));
axWindowsMediaPlayer.currentPlaylist = p2;
CreatePlaylist(_currentId, p2);
}
//axWindowsMediaPlayer.BringToFront();
}
axWindowsMediaPlayer.Ctlcontrols.play();
}
}
}
Others have already mentioned the problem. The specific type you would want is IWMPPlaylist, so the full line will look like this.
IWMPPlaylist p2 = axWindowsMediaPlayer.playlistCollection.newPlaylist("Playlist 1");

How prevent this loop?

I cannot figure out how to fix this loop issue when i call a function like
new Common.Utility.Parameter().Get(Common.Constants.Parameter.SomeParameter);
Probably the error is caused by isHttpsCookie that recall the Parameter.Get()
Utility.cs
public static class Utility
{
public class Parameter
{
public string Get(string key)
{
string cookie = new Cookie().Read(key);
if (cookie == null)
{
var parameter = new Models.Parameter();
using (var db = new MyEntities())
parameter = db.Parameters.Where(w => w.Key == key).FirstOrDefault<Models.Parameter>();
if (parameter != null)
{
new Cookie().Write(key, parameter.Value);
return parameter.Value;
}
else
return string.Empty;
}
else
return cookie;
}
}
}
Cookie.cs
public class Cookie
{
private bool isHttpsCookie = Convert.ToBoolean(new Utility.Parameter().Get(Constants.Parameter.IsHttps)); // Loop here?
public string Read(string cookieName)
{
HttpCookie httpCookie = HttpContext.Current.Request.Cookies[HttpContext.Current.ApplicationInstance.GetType().BaseType.Assembly.GetName().Na​me + "_" + cookieName];
return httpCookie != null ? HttpContext.Current.Server.HtmlEncode(httpCookie.Value).Trim() : string.Empty;
}
public void Write(string cookieName, string cookieValue, bool isHttpCookie = true)
{
if (isHttpsCookie)
isHttpCookie = false;
var aCookie = new HttpCookie(HttpContext.Current.ApplicationInstance.GetType().BaseType.Assembly.G​etName().Name + "_" + cookieName)
{Value = cookieValue, Expires = Common.Constants.Cookie.DefaultExpires, HttpOnly = isHttpCookie};
HttpContext.Current.Response.Cookies.Add(aCookie);
}
}
Apparently, your code is falling into a sort of recursion where you suspect it is. What I'm having trouble with is why are you creating new objects just to call a single method. Looks like you could have them as static methods in your classes, so no object creation would be needed, thus no 'looping'.
Have a closer look at your Cookie.Write() and Parameter.Get() method, they are calling each other. When you declare isHttpsCookie, you call Parameter.Get(). In the Parameter.Get(), if the condition is valid, it will call to Cookie.Write(). In its turn, when you call new Cookie(), the isHttpsCookie is called again and it's continuing forever.
Another point at this code:
if (isHttpsCookie)
isHttpCookie = false;
do you try to say that isHttpsCookie should be false at all time? so why do you need to declare this?
Solution: Do like #Takeshi said: those methods can be declared as static so no class declaration is required to called them.
You are correct in what you suspect. the isHttpsCookie declaration is causing you grief.
When the Cookie object is created it goes away and executes the method get from your utility class which creates an instance of cookie. Therefor you have your recursion.
You will need to change the way you initialise isHttpsCookie. Maybe only initialise / check if you are doing a write. After all you are most likely going to read more often than write.
Hope that helps.

Constructor pointing to a property not accesing set keyword

I'm just learning C# and trying to get some practice working with classes as opposed to writing everything in Main, so I'm trying to write a console game of hangman.
I'm initializing the guessed letter with this line:
Guess guess = new Guess(Console.ReadLine());
Which points to this constructor in the Guess.cs file:
public Guess(string guessString)
{
CurrentGuess = Convert.ToChar(guessString);
}
CurrentGuess referring to this property:
private char currentGuess
public char CurrentGuess
{
get
{
return currentGuess;
}
set
{
foreach (char letter in guessList)
{
if (letter == value)
{
GuessedAlready = true;
break;
}
}
if (GuessedAlready == false)
{
value = currentGuess;
guessesMade++;
guessList[guessesMade-1] = value;
}
}
}
When I run the program and input a char value, it isn't getting set to currentGuess. Also Visual Studio is telling me that currentGuess is never getting assigned to, and is keeping it's current value (which is blank).
Why isn't the set keyword working? I've followed the path to currentGuess over and over and I can't see it, so I'm assuming it's a reason I don't know yet.
Any help would be appreciated!
You have to swap this assingment in your setter
value = currentGuess;
into
currentGuess = value;
In the set method the value is the incoming parameter. In your case you want to store that value in your local class variable curtentGuess;

Categories

Resources