use 1 line of code instead of the use the same code - c#

I have code like this:
string FileName = "Users.json";
var DeserializeOptions = new JsonSerializerOptions { AllowTrailingCommas = true };
string jsonstring = File.ReadAllText(FileName);
var result = JsonSerializer.Deserialize<Root>(jsonstring, DeserializeOptions);
Root is list of 2 objects: Monsters and People. I use these 4 lines of code in my win forms program more than 10 times. Is it possible to change this code for class and use in other .cs files using shorter code?

Sure - put your code into a method:
internal static class MyUtilities
{
public static Root DoMyStuff()
{
string FileName = "Users.json";
var DeserializeOptions = new JsonSerializerOptions { AllowTrailingCommas = true };
string jsonstring = File.ReadAllText(FileName);
return JsonSerializer.Deserialize<Root>(jsonstring, DeserializeOptions);
}
}
Depending on your use case and the case your code varies across those different instances (not sure whether it is 100% the same, or uses different filenames, for example), you may want to accept some of those values as parameters.
In any case, you can then replace all of your code by single lines like this:
var result = MyUtilities.DoMyStuff();

Related

How do I get two integer values from an input, Console.ReadLine(), in C#?

class Program
{
static void Main(string[] args)
{
var information= Console.ReadLine();
var one= Int32.Parse(informatie.Split(' ')[0]);
var two = Int32.Parse(informatie.Split(' ')[1]);
}
}
I want the user to type in two numbers, seperated by a whitespace, for example: 5 2. I want to capture the first number (5) in var one and the second number (2) in var two. The problem, however, is that my code doesn't work if the user, for example, types in two-digit numbers such as: 25 10. How can I make it work that my two variables one and two capture the numbers regardless of length? So another example, if a user types in: 348 3910 I want var one = 348 and var two = 3910. Another one: 2 4 , var one = 2 and var two = 4.
You need to first split the string and then select the value from the array you want to use. You do not need to perform the split operation each time; you only need to do it once. See the below code sample. You can also see it in this fiddle.
var textSample = "320 520";
var textSplit = textSample.Split(' ');
Console.WriteLine(Int32.Parse(textSplit[0]));
Console.WriteLine(Int32.Parse(textSplit[1]));
Your code would look like this
var information= Console.ReadLine();
var textSplit = informatie.Split(' ')
var one= Int32.Parse(textSplit[0]);
var two = Int32.Parse(textSplit[1]);
I tried this one:
class Program
{
static void Main(string[] args)
{
var information = Console.ReadLine();
var one = Int32.Parse(information.Split(' ')[0]);
var two = Int32.Parse(information.Split(' ')[1]);
Console.WriteLine($" one is {one}");
Console.WriteLine($" two is {two}");
Console.ReadKey();
}
}
and it works
This is the console: (Click here to see image...)

Can't use the .length property with IronJS and ArrayObject

I am using IronJs's latest version (0.2.0.1) and my js scripts do not properly retrieve the length of an array that has been set to the js engine using an IronJs.Runtime.ArrayObject. However, my variable is well recognized as an array, as shown in C# code below.
var jsCode = #"myArray.length;";
var javascriptEngine = new IronJS.Hosting.CSharp.Context();
var array = new ArrayObject(javascriptEngine.Environment, 2);//array of size 2
array.Put(0, 12.0);//mock values
array.Put(1, 45.1);
javascriptEngine.SetGlobal<ArrayObject>("myArray", array);
var result = javascriptEngine.Execute(jsCode);
Console.WriteLine(result);
var jsCode2 = #"myArray instanceof Array;";
var result2 = javascriptEngine.Execute<bool>(jsCode2);
Console.WriteLine(result2);
We get the following output
undefined
True
This is a bug in IronJS Runtime. You should open an issue in the appropriate GitHub repository : https://github.com/fholm/IronJS/
A workaround is to force a reallocation of the whole array. In that case, the .length property seems to be correctly set. A hackish way to accomplish that is to create a smaller than needed ArrayObject (e.g. a 0-sized ArrayObject), then put some values in it. The following test passes :
[TestMethod]
public void TestWithZeroSizedArray()
{
string jsCode = #"myArray.length;";
var javascriptEngine = new IronJS.Hosting.CSharp.Context();
var array = new ArrayObject(javascriptEngine.Environment, 0); // Creates a 0-sized Array
array.Put(0, 12.0);
array.Put(1, 45.1);
javascriptEngine.SetGlobal<ArrayObject>("myArray", array);
var result = javascriptEngine.Execute(jsCode);
Assert.AreEqual(2, result);
}
Keep in mind that the multiple copy/reallocations of the underlying .NET arrays will lead to performance issues.

How to organize a large number of file/directory path constants

I have a static class where I keep a large number of relative paths that are used in different places in my application. It looks like that:
static class FilePathConstants
{
public const string FirstDirectory = "First";
public const string FirstSecondDirectory = "First/Second";
public const string FirstSecondThirdFileA = "First/Second/Third/FileA";
public const string FirstSecondFourthFileB = "First/Second/Fourth/FileB";
... nearly 100 of similar members
}
All of them are relative to some parent directory, location of which I know only during the program run. I need to keep them all together because it allows me to easily control what files are used by my application and change their locations from time to time.
However even though they are organized in alphabetic order and its easy to find a certain path, I need to be able to change some of them depending on some setting. Lets say, there is a setting 'bool SettingA' and when I turn it on, I have to do modify some of the paths to use a different directory or a different file name.
The problem is that now I can't use constants, I have to rewrite my code to properties or methods so that I can change file paths at runtime. And here where my code becomes much bigger in size and the strict order now looks ugly. Is there a way I can group them, so that it will not confuse anybody who uses this code? I can't break them into a separate classes because it is difficult to remember in what class what constant you may keep. For now I'm grouping them by regions, but I have a bad feeling that keeping more than one hundred of properties in one class is wrong.
Edit:
All directories and files that I declare in FilePathConstants are used in a large number of places in application (each path can be used multiple times, taking into account the fact that there is more then one hundred of paths - this is a large number). I would like to keep the interface of this class the same or with minimum changes to other classes that use them.
maybe you could use rowstructs
Use something like "index" file to store the directory paths and load it in runtime.
const string indexFilePath = #"C:\dirlist.txt";
IEnumerable<string> paths = File.ReadAllLines(indexFilePath);
Update
I would like to suggest using indirection - "mapper" class.
Here is how it should look like.
public enum FileSystemElement
{
FirstDirectory,
FirstSecondDirectory,
FirstSecondThirdFileA,
FirstSecondFourthFileB
}
public class FileSystemMapper
{
private readonly string _rootDirectory;
private readonly Dictionary<FileSystemElement, string> _fileElements;
public FileSystemMapper(string rootDirectory, string fileName)
{
_rootDirectory = rootDirectory;
string[] lines = File.ReadAllLines(fileName);
_fileElements = lines.Select(ParsePair).ToDictionary(pair => pair.Key, pair => pair.Value);
}
public string GetPath(FileSystemElement element)
{
string relativePath;
if (!_fileElements.TryGetValue(element, out relativePath))
{
throw new InvalidOperationException("Element not found");
}
string resultPath = Path.Combine(_rootDirectory, relativePath);
return resultPath;
}
private static KeyValuePair<FileSystemElement, string> ParsePair(string line)
{
const string separator = "|";
// File element alias | Path
if (string.IsNullOrEmpty(line))
throw new ArgumentException("Null or empty line", "line");
string[] components = line.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries);
if (components.Length != 2)
throw new ArgumentException("Line has invalid format", "line");
FileSystemElement element;
bool parseResult = FileSystemElement.TryParse(components[0], out element);
if (!parseResult)
throw new ArgumentException("Invalid element name", "line");
string path = components[1]; // for clarity
return new KeyValuePair<FileSystemElement, string>(element, path);
}
Client example:
FileSystemMapper fileSystemMapper = new FileSystemMapper(#"C:\root", #"C:\dirs.txt");
string firstDirectory = fileSystemMapper.GetPath(FileSystemElement.FirstDirectory);
string secondDirectory = fileSystemMapper.GetPath(FileSystemElement.FirstSecondDirectory);
string secondThirdFile = fileSystemMapper.GetPath(FileSystemElement.FirstSecondThirdFileA);
Index file format: <Element name>|<Path><New Line>
Example:
FirstDirectory|First
FirstSecondDirectory|First\Second
FirstSecondThirdFileA|First\Second\Third\FileA
FirstSecondFourthFileB|First\Second\Fourth\FileB
can you not use your projects Properties.Settings? it's stored in the .config file so can be edited after deployment
or just dont make them const, then you can edit them at runtime bu they revert to the original setting on next run.
or dont make the calss static and create an instance each time you use it, then change whats needed and discard the instance when finished.

Best way to build XML from XElements where many elements are shared?

Note: I've read this and its not quite what I'm looking for:
I have an app that builds up XML from an input file and creates one of two outputs, depending upon the file chosen. It was a "quick n dirty" app to get round an immediate problem, but I know it's going to find further use and want to pre-empt this by refactoring.
At the moment I have a "builder" class that takes the input (in its ctor) and exposes a property which is the required XElement. However, many of the XElements are identical, except for the content, for both of my XML outputs. (Oh, please ignore the validation part which I'll refactor separately)
So I'm looking at a sensible way of DRYing my app:
At the moment I have something like this.
public FirstBuilder(string line, int lineNumber, bool output, string subjectType, string inquiryCode)
{
var split = Regex.Split(line, #"\|");
if (split.Count() != SPLIT_COUNT)
throw new Exception("This does not appear to be a valid First Type input file.");
_lineNumber = lineNumber;
_reportId = output ? TXT_REPORT_ID : XML_REPORT_ID;
_subjectType = subjectType;
_responseType = output ? TXT_RESPONSE_TYPE : XML_REPONSE_TYPE;
_inquiryCode = inquiryCode;
_product = split[0];
_number = split[1];
_amount = split[2];
_currency = split[3];
_name = split[4];
_nationalId = split[5];
_gender = split[6];
_dateOfBirth = split[7];
_nationality = split[8];
}
public XElement RequestElement
{
get
{
return new XElement("REQUEST",
new XAttribute("REQUEST_ID", _lineNumber),
RequestParametersElement,
SearchParametersElement);
}
}
private XElement RequestParametersElement
{
get
{
return new XElement("REQUEST_PARAMETERS",
ReportParametersElement,
InquiryPurposeElement,
ApplicationElement);
}
}
private XElement ReportParametersElement
{
get
{
return new XElement("REPORT_PARAMETERS",
new XAttribute("REPORT_ID", _reportId),
new XAttribute("SUBJECT_TYPE", _subjectType),
new XAttribute("RESPONSE_TYPE", _responseType));
}
}
etc. etc...
//used by
var x = new FirstBuilder(x,y,z,etc.).RequestElement();
This all works and is very fast...but SecondBuilder also uses these same elements, along with some different ones.
So I'm looking at the "best" way to refactor these out:
Shared Abstract class with inheritance?
Shared "Helper" classes?
Extension methods to return "built" elements?
Classes per element that extend XElement?
My suspicion is that this will balloon from the two examples as a quick solution to around 30 in then next month!
THX.
I would refactor the private properties to methods that receive the required values as input parameters. You can then move them into a PartsBuilder class and use that one in you concrete builders.

turn javascript array into c# array

Hey. I have this javascript file that I'm getting off the web and it consists of basically several large javascript arrays. Since I'm a .net developer I'd like for this array to be accessible through c# so I'm wondering if there are any codeplex contributions or any other methods that I could use to turn the javascript array into a c# array that I could work with from my c# code.
like:
var roomarray = new Array(194);
var modulearray = new Array(2055);
var progarray = new Array(160);
var staffarray = new Array(3040);
var studsetarray = new Array(3221);
function PopulateFilter(strZoneOrDept, cbxFilter) {
var deptarray = new Array(111);
for (var i=0; i<deptarray.length; i++) {
deptarray[i] = new Array(1);
}
deptarray[0] [0] = "a/MPG - Master of Public Governance";
deptarray[0] [1] = "a/MPG - Master of Public Governance";
deptarray[1] [0] = "a/MBA_Flex MBA 1";
deptarray[1] [1] = "a/MBA_Flex MBA 1";
deptarray[2] [0] = "a/MBA_Flex MBA 2";
deptarray[2] [1] = "a/MBA_Flex MBA 2";
deptarray[3] [0] = "a/cand.oecon";
deptarray[3] [1] = "a/cand.oecon";
and so forth
This is what I'm thinking after overlooking the suggestions:
Retrieve the javascript file in my c# code by making an httprequest for it
paste it together with some code i made myself
from c# call an execute on a javascript function selfmade function that will turn the javascript array into json (with help from json.org/json2.js), and output it to a new file
retrieve the new file in c# parsing the json with the DataContractJsonSerializer resulting hopefully resulting in a c# array
does it sound doable to you guys?
I'm not in front of a computer with c# right now so I'm not able to fully try this.
What you're going to need to do #Jakob is the following:
Write a parser that will download the file and store it in memory.
For each section that you want to "parse" into a c# array (for example zonearray), you need to setup bounds to begin searching and end searching the file. Example: We know that zonearray starts building the array the two lines after zonearray[i] = new Array(1); and ends on zonearray.sort().
So with these bounds we can then zip through each line between and parse a C# array. This is simple enough I think that you can figure out. You'll need to keep track of sub-index as well remember.
Repeat this 2-3 for each array you want to parse (zonearray, roomarray..etc).
If you can't quite figure out how to code the bounds or how to parse the line and dump them into arrays, I might be able to write something tomorrow (even though it's a holiday here in Canada).
EDIT: It should be noted that you can't use some JSON parser for this; you have to write your own. It's not really that difficult to do, you just need to break it into small steps (first figure out how to zip through each line and find the right "bounds").
HTH
EDIT: I just spent ~20 minutes writing this up for you. It should parse the file and load each array into a List<string[]>. I've heavily commented it so you can see what's going on. If you have any questions, don't hesitate to ask. Cheers!
private class SearchBound
{
public string ArrayName { get; set; }
public int SubArrayLength { get; set; }
public string StartBound { get; set; }
public int StartOffset { get; set; }
public string EndBound { get; set; }
}
public static void Main(string[] args)
{
//
// NOTE: I used FireFox to determine the encoding that was used.
//
List<string> lines = new List<string>();
// Step 1 - Download the file and dump all the lines of the file to the list.
var request = WebRequest.Create("http://skema.ku.dk/life1011/js/filter.js");
using (var response = request.GetResponse())
using(var stream = response.GetResponseStream())
using(var reader = new StreamReader(stream, Encoding.GetEncoding("ISO-8859-1")))
{
string line = null;
while ((line = reader.ReadLine()) != null)
{
lines.Add(line.Trim());
}
Console.WriteLine("Download Complete.");
}
var deptArrayBounds = new SearchBound
{
ArrayName = "deptarray", // The name of the JS array.
SubArrayLength = 2, // In the JS, the sub array is defined as "new Array(X)" and should always be X+1 here.
StartBound = "deptarray[i] = new Array(1);",// The line that should *start* searching for the array values.
StartOffset = 1, // The StartBound + some number line to start searching the array values.
// For example: the next line might be a '}' so we'd want to skip that line.
EndBound = "deptarray.sort();" // The line to stop searching.
};
var zoneArrayBounds = new SearchBound
{
ArrayName = "zonearray",
SubArrayLength = 2,
StartBound = "zonearray[i] = new Array(1);",
StartOffset = 1,
EndBound = "zonearray.sort();"
};
var staffArrayBounds = new SearchBound
{
ArrayName = "staffarray",
SubArrayLength = 3,
StartBound = "staffarray[i] = new Array(2);",
StartOffset = 1,
EndBound = "staffarray.sort();"
};
List<string[]> deptArray = GetArrayValues(lines, deptArrayBounds);
List<string[]> zoneArray = GetArrayValues(lines, zoneArrayBounds);
List<string[]> staffArray = GetArrayValues(lines, staffArrayBounds);
// ... and so on ...
// You can then use deptArray, zoneArray etc where you want...
Console.WriteLine("Depts: " + deptArray.Count);
Console.WriteLine("Zones: " + zoneArray.Count);
Console.WriteLine("Staff: " + staffArray.Count);
Console.ReadKey();
}
private static List<string[]> GetArrayValues(List<string> lines, SearchBound bound)
{
List<string[]> values = new List<string[]>();
// Get the enumerator for the lines.
var enumerator = lines.GetEnumerator();
string line = null;
// Step 1 - Find the starting bound line.
while (enumerator.MoveNext() && (line = enumerator.Current) != bound.StartBound)
{
// Continue looping until we've found the start bound.
}
// Step 2 - Skip to the right offset (maybe skip a line that has a '}' ).
for (int i = 0; i <= bound.StartOffset; i++)
{
enumerator.MoveNext();
}
// Step 3 - Read each line of the array.
while ((line = enumerator.Current) != bound.EndBound)
{
string[] subArray = new string[bound.SubArrayLength];
// Read each sub-array value.
for (int i = 0; i < bound.SubArrayLength; i++)
{
// Matches everything that is between an equal sign then the value
// wrapped in quotes ending with a semi-colon.
var m = Regex.Matches(line, "^(.* = \")(.*)(\";)$");
// Get the matched value.
subArray[i] = m[0].Groups[2].Value;
// Move to the next sub-item if not the last sub-item.
if (i < bound.SubArrayLength - 1)
{
enumerator.MoveNext();
line = enumerator.Current;
}
}
// Add the sub-array to the list of values.
values.Add(subArray);
// Move to the next line.
if (!enumerator.MoveNext())
{
break;
}
}
return values;
}
If I understand your question right, you are asking whether you can execute JavaScript code from C#, and then pass the result (which in your example would be a JavaScript Array object) into C# code.
The answer is: Of course it’s theoretically possible, but you would need to have an actual JavaScript interpreter to execute the JavaScript. You’ll have to find one or write your own, but given that JavaScript is a full-blown programming language, and writing interpreters for such a large and full-featured programming language is quite an undertaking, I suspect that you won’t find a complete ready-made solution, nor will you be able to write one unless your dedication exceeds that of all other die-hard C#-and-JavaScript fans worldwide.
However, with a bit of trickery, you might be able to coerce an existing JavaScript interpreter to do what you want. For obvious reasons, all browsers have such an interpreter, including Internet Explorer, which you can access using the WinForms WebBrowser control. Thus, you could try the following:
Have your C# code generate an HTML file containing the JavaScript you downloaded plus some JavaScript that turns it into JSON (you appear to have already found something that does this) and outputs it in the browser.
Open that HTML file in the WebBrowser control, have it execute the JavaScript, and then read the contents of the website back, now that it contains the result of the executed JavaScript.
Turn the JSON into a C# array using DataContractJsonSerializer as you suggested.
This is a pretty roundabout way to do it, but it is the best I can think of.
I have to wonder, though, why you are retrieving a JavaScript file from the web in the first place. What generates this JavaScript file? Whatever generates it, surely could generate some properly readable stuff instead (e.g. an XML file)? If it is not generated but written by humans, then why is it written in JavaScript instead of XML, CSV, or some other data format? Hopefully with these thoughts you might be able to find a solution that doesn’t require JavaScript trickery like the above.
Easiest solution is to just execute the Javascript function that makes the array. Include there a function that makes it an JSON (http://www.json.org/js.html). After that make a XMLHttpRequest (AJAX) to the server and from there extract the JSON to a custom class.
If I may use jQuery, here's an example of the needed Javascript:
var myJSONText = JSON.stringify(deptarray);
(function($){
$.ajax({
type: "POST",
url: "some.aspx",
data: myJSONText,
success: function(msg){
alert( "Data Saved: " + msg );
}
});
})(jQuery);
Only now need some code to rip the JSON string to an C# Array.
EDIT:
After looking around a bit, I found Json.NET: http://json.codeplex.com/
There are also a lot of the same questions on Stackoverflow that ask the same.

Categories

Resources