I'm trying to dynamically build a c# class from small pieces of code. We have a window where a user can enter c# code (valid or not), and we parse these strings into roslyn. I recently found an issue when i was using this :
public override IEnumerable<StatementSyntax> GenerateStatements()
{
var result = new List<StatementSyntax>();
if (!string.IsNullOrWhiteSpace(this.Tag.Code))
{
result.Add(SyntaxFactory.ParseStatement(this.Tag.Code));
}
return result;
}
Turns out when compiling in VB, if the statement is multiline, it would inline all the text, even in c#.
I then made an helper class to parse it into a dummy class and method to get a list of parsed statements.
public override IEnumerable<StatementSyntax> GenerateStatements()
{
var result = new List<StatementSyntax>();
if (!string.IsNullOrWhiteSpace(this.Tag.Code))
{
foreach (var statement in SyntaxFactoryHelper.ParseStatements(this.Tag.Code))
{
result.Add(statement);
}
}
return result;
}
public static StatementSyntax[] ParseStatements(string code)
{
var blockCode = string.Format(CultureInfo.InvariantCulture, "public class C {{ public void M() {{ {0} }} }}", code);
var compilationUnit = SyntaxFactory.ParseCompilationUnit(blockCode);
return compilationUnit
.ChildNodes().OfType<ClassDeclarationSyntax>().First(c => c.Identifier.Text == "C")
.ChildNodes().OfType<MethodDeclarationSyntax>().First(m => m.Identifier.Text == "M")
.ChildNodes().OfType<BlockSyntax>().First()
.Statements.ToArray();
}
Here's my issue.
If i have 3 statements in my applications.
for (var i = 0; i < 10; i++)
{
then
i.ToString()
and finally
}
It auto-closes the curly braces of the first statement, so I lose my scope.
Is there a way to parse invalid code and avoid this kind of behavior?
I know inlined code is valid in c#, but we are facing the same issue with VB.
Thanks for your help :)
Related
I know it's possible to check whether the value of a text box or variable is numeric using try/catch statements, but IsNumeric is so much simpler. One of my current projects requires recovering values from text boxes. Unfortunately, it is written in C#.
I understand that there's a way to enable the Visual Basic IsNumeric function in Visual C# by adding a reference to Visual Basic, though I don't know the syntax for it. What I need is a clear and concise walkthrough for enabling the IsNumeric function in C#. I don't plan on using any other functions indigenous to Visual Basic.
public bool IsNumeric(string value)
{
return value.All(char.IsNumber);
}
To totally steal from Bill answer you can make an extension method and use some syntactic sugar to help you out.
Create a class file, StringExtensions.cs
Content:
public static class StringExt
{
public static bool IsNumeric(this string text)
{
double test;
return double.TryParse(text, out test);
}
}
EDIT: This is for updated C# 7 syntax. Declaring out parameter in-line.
public static class StringExt
{
public static bool IsNumeric(this string text) => double.TryParse(text, out _);
}
Call method like such:
var text = "I am not a number";
text.IsNumeric() //<--- returns false
You could make a helper method. Something like:
public bool IsNumeric(string input) {
int test;
return int.TryParse(input, out test);
}
It is worth mentioning that one can check the characters in the string against Unicode categories - numbers, uppercase, lowercase, currencies and more. Here are two examples checking for numbers in a string using Linq:
var containsNumbers = s.Any(Char.IsNumber);
var isNumber = s.All(Char.IsNumber);
For clarity, the syntax above is a shorter version of:
var containsNumbers = s.Any(c=>Char.IsNumber(c));
var isNumber = s.All(c=>Char.IsNumber(c));
Link to unicode categories on MSDN:
UnicodeCategory Enumeration
Using C# 7 (.NET Framework 4.6.2) you can write an IsNumeric function as a one-liner:
public bool IsNumeric(string val) => int.TryParse(val, out int result);
Note that the function above will only work for integers (Int32). But you can implement corresponding functions for other numeric data types, like long, double, etc.
http://msdn.microsoft.com/en-us/library/wkze6zky.aspx
menu:
Project-->Add Reference
click: assemblies, framework
Put a checkmark on Microsoft.VisualBasic.
Hit OK.
That link is for Visual Studio 2013, you can use the "Other versions" dropdown for different versions of visual studio.
In all cases you need to add a reference to the .NET assembly "Microsoft.VisualBasic".
At the top of your c# file you neeed:
using Microsoft.VisualBasic;
Then you can look at writing the code.
The code would be something like:
private void btnOK_Click(object sender, EventArgs e)
{
if ( Information.IsNumeric(startingbudget) )
{
MessageBox.Show("This is a number.");
}
}
Try following code snippet.
double myVal = 0;
String myVar = "Not Numeric Type";
if (Double.TryParse(myVar , out myNum)) {
// it is a number
} else {
// it is not a number
}
I usually handle things like this with an extension method. Here is one way implemented in a console app:
namespace ConsoleApplication10
{
class Program
{
static void Main(string[] args)
{
CheckIfNumeric("A");
CheckIfNumeric("22");
CheckIfNumeric("Potato");
CheckIfNumeric("Q");
CheckIfNumeric("A&^*^");
Console.ReadLine();
}
private static void CheckIfNumeric(string input)
{
if (input.IsNumeric())
{
Console.WriteLine(input + " is numeric.");
}
else
{
Console.WriteLine(input + " is NOT numeric.");
}
}
}
public static class StringExtensions
{
public static bool IsNumeric(this string input)
{
return Regex.IsMatch(input, #"^\d+$");
}
}
}
Output:
A is NOT numeric.
22 is numeric.
Potato is NOT numeric.
Q is NOT numeric.
A&^*^ is NOT numeric.
Note, here are a few other ways to check for numbers using RegEx.
Tested with Net6 and universal with object because needed in my app:
public static bool IsNumeric(this object text) => double.TryParse(Convert.ToString(text), out _);
Works with null and string.empty and also tested "".
Is numeric can be achieved via many ways, but i use my way
public bool IsNumeric(string value)
{
bool isNumeric = true;
char[] digits = "0123456789".ToCharArray();
char[] letters = value.ToCharArray();
for (int k = 0; k < letters.Length; k++)
{
for (int i = 0; i < digits.Length; i++)
{
if (letters[k] != digits[i])
{
isNumeric = false;
break;
}
}
}
return isNumeric;
}
Let's say I have the following code point: u1F64A (which is the 🙊 emoji).
This can be written as:
string monkey = "\u1F64A";
How would I convert a known codepoint (as an integer) to a string at runtime though?
int codepoint = 0xF64A;
string monkey = //?
When I want to play with Emojis in C#, I build a helper class just like this:
public class Emoji
{
readonly int[] codes;
public Emoji(int[] codes)
{
this.codes = codes;
}
public Emoji(int code)
{
codes = new int[] { code };
}
public override string ToString()
{
if (codes == null)
return string.Empty;
var sb = new StringBuilder(codes.Length);
foreach (var code in codes)
sb.Append(Char.ConvertFromUtf32(code));
return sb.ToString();
}
}
This way, I can just do string monkeyEmoji = new Emoji(0xF64A);
It also supports emojis with multiple code points (yes, those exist and are a pain)
Is the above code even compilable? It doesn't compile on my machine.
And why should it, \u1F64A is not a valid string.
I think what could work is string monkey = $"{char.ConvertToUtf32((char) 0xF64, 'A')}", but that is just a guess. I just answered to clarify that the first line of code you wrote is not compilable on my machine.
I have C++ code that I want to convert to C# code. But I don't know how to use register keyword in C#. How can I convert to C# following code?
int InsertNode(register Node **linkp, Node * inserted_node)
{
register Node *current;
while ((current = *linkp) != NULL && current->value > inserted_node->value)
{
linkp = ¤t->link;
}
inserted_node->link = current;
*linkp = inserted_node;
return TRUE;
}
The C code you posted uses the register keyword to attempt to force a particular optimization on the compiler. This doesn't change anything about the way the code works, only about how the compiler generates the machine code that will ultimately run on the CPU.
The reality is that this sort of compiler hinting is largely unnecessary with modern compilers, and can actually reduce the efficiency of the output code as it juggles to try to accommodate your demands that a particular piece of information be kept on the CPU. Optimizers are smart enough these days to figure out what does and doesn't need to be on the CPU, we can trust them that far most of the time.
As for C# though... there is no compatible concept. There are also no safe pointers, so you'll have to get rid of those. Just use references instead, they work find for linked lists.
Try this:
public class LinkedList<T>
where T : IComparable<T>
{
public class Node
{
public Node link;
public T value;
}
public Node root = null;
public bool InsertValue(T value)
{
return InsertNode(new Node { value = value });
}
public bool InsertNode(Node inserted_node)
{
if (root == null)
{
root = inserted_node;
return true;
}
Node prev = null;
Node current = root;
while (current != null && current.value.CompareTo(inserted_node.value) > 0)
{
prev = current;
current = current.link;
}
prev.link = inserted_node;
inserted_node.link = current;
return false;
}
}
Usage example:
void Main()
{
var list = new LinkedList<int>();
list.InsertValue(5);
list.InsertValue(2);
list.InsertValue(3);
for (var c = list.root; c != null; c = c.link)
Console.WriteLine(c.value);
}
register does nothing in C++. In C it is a hint to compiler to place variable in register, which it can ignore.
You can just throw away register keyword. I would be surprised if it changes anything in resulting binary.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C# - Parse Math Expression
C#, User defined formula
The equation will only use addition, subtraction, multiplication, division operators and will not use brackets. I didn't think it would be so difficult, but I've been thinking about it for hours while trying different things and writing different ideas out.
I thought there might be some way by splitting the string on each of those characters and doing something with the output or by looping through the string character by character and coming up with something, but I'm not clever enough I guess.
Anyways, I'd love to hear other peoples' ideas because I'm stumped. I don't want to use a third-party library of some kind which is what everybody has suggested in old threads that I've been looking at.
For such simple equations it could be implemented with a split and two loops.
For a string like this: "4+5*6/2-8"
Split on operators, keeping them in the result:
"4", "+", "5", "*", "6", "/", "2", "-", "8"
Loop though the operators and calculate multiplication and division, putting the result back in the list:
"4", "+", "30", "/", "2", "-", "8"
"4", "+", "15", "-", "8"
Loop through the operators again and calculate addition and subtraction this time:
"19", "-", "8"
"11"
The easiest way to do that is take advantage of the JIT compiler to evaluate a calculation. Thant's what it's there for. you can even pass in code like Math.Acos(4) to the expression, or "create" a function Acos in the object you are using to allow users not to have to worry about the Math. prefix.
string code = string.Format // Note: Use "{{" to denote a single "{"
(
"public static class Func{{ public static Acos(double d) { return Math.ACos(d); }
public static int func(){{ return {0};}}}}", expression
);
Also you can include additional namespaces if you need any other functions, but Without any extra functions the code is like this:
using System;
using System.Reflection;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
class Program
{
static void Main()
{
TestExpression("2+1-(3*2)+8/2");
TestExpression("1*2*3*4*5*6");
TestExpression("Invalid expression");
}
static void TestExpression(string expression)
{
try
{
int result = EvaluateExpression(expression);
Console.WriteLine("'" + expression + "' = " + result);
}
catch (Exception)
{
Console.WriteLine("Expression is invalid: '" + expression + "'");
}
}
public static int EvaluateExpression(string expression)
{
string code = string.Format // Note: Use "{{" to denote a single "{"
(
"public static class Func{{ public static int func(){{ return {0};}}}}", expression
);
CompilerResults compilerResults = CompileScript(code);
if (compilerResults.Errors.HasErrors)
{
throw new InvalidOperationException("Expression has a syntax error.");
}
Assembly assembly = compilerResults.CompiledAssembly;
MethodInfo method = assembly.GetType("Func").GetMethod("func");
return (int)method.Invoke(null, null);
}
public static CompilerResults CompileScript(string source)
{
CompilerParameters parms = new CompilerParameters();
parms.GenerateExecutable = false;
parms.GenerateInMemory = true;
parms.IncludeDebugInformation = false;
CodeDomProvider compiler = CSharpCodeProvider.CreateProvider("CSharp");
return compiler.CompileAssemblyFromSource(parms, source);
}
}
The answer was copied from http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/abff98e3-93fe-44fa-bfd4-fcfe297dbc43/ for I did not like writing the code myself and thanks to Matthew Watson
I didn't have to.
I prefer Recursive Descent Parsing, as stated in a comment. Here is a very quick partial adaptation in C# of the C example found in the linked Wikipedia article.
I find a simple recursive-descent easier to read than the shunting yard method (notice how recursive descent functions closely match EBNF non-terminal definitions) and more extensible. The following can be trivially adapted to allow for parenthesis or "external" functions.
A more robust implementation would actually support symbol classes and handle invalid grammars more gracefully; once again, trivial to add in such a recursive descent parsing setup. Tokening the input (read: splitting the string and converting numbers to double) is left as an exercise to the reader.
class RecDec {
St x; // ugly shared state, it's a quick example
public double eval (params object[] tokens) {
x = new St(tokens);
return expression();
}
double expression() {
double res = term();
string accepted;
while ((accepted = x.acceptOp(new [] {"+", "-"})) != null) {
res = accepted == "+"
? res + term()
: res - term();
}
return res;
}
double term() {
double res = factor();
string accepted;
while ((accepted = x.acceptOp(new [] {"*", "/"})) != null) {
res = accepted == "*"
? res * factor();
: res / factor();
}
return res;
}
double factor() {
var val = x.acceptVal();
if (val == null) {
throw new Exception(x.ToString());
}
return (double)val;
}
}
The "state" / token-feader class:
class St {
IEnumerable<object> src;
public St (IEnumerable<object> src) {
this.src = src;
}
public object acceptVal () {
var first = src.FirstOrDefault();
if (first is double) {
src = src.Skip(1);
return first;
} else {
return null;
}
}
public string acceptOp (params string[] syms) {
var first = src.FirstOrDefault();
if (syms.Contains(first)) {
src = src.Skip(1);
return (string)first;
} else {
return null;
}
}
public override string ToString () {
return "[" + string.Join(",", src.ToArray()) + "]";
}
}
And usage (Dump is a LINQPad extension method, use eval return value as applicable):
void Main()
{
var rd = new RecDec();
// Use results - i.e. Remove Dump - if not on LINQPad
rd.eval(1d, "+", 2d).Dump();
rd.eval(2d, "*", 1d, "+", 2d, "*", 9d, "/", 4d).Dump();
}
I've downloaded the VCSharpSample pack from Microsoft and started reading on Anonymous Delegates. I can more or less understand what the code is doing, but I don't understand the reason behind it. Maybe if you gave me some examples where it would result in cleaner code and easier maintainability then I could wrap my head around it. :)
Can you help?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
delegate decimal CalculateBonus(decimal sales);
class Player
{
public string Name;
public decimal Score;
public decimal Bonus;
public CalculateBonus calculation_algorithm;
}
class Program
{
static decimal calculateStandardBonus(decimal sales)
{
return sales / 10;
}
static void Main(string[] args)
{
decimal multiplier = 2;
CalculateBonus standard_bonus = new CalculateBonus(calculateStandardBonus);
CalculateBonus enhanced_bonus = delegate(decimal sales) { return multiplier * sales / 10; };
Player[] players = new Player[5];
for (int i = 0; i < 5; i++)
{
players[i] = new Player();
}
players[0].Name = "Sergio";
players[0].Score = 240;
players[0].calculation_algorithm = standard_bonus;
players[1].Name = "Sergio";
players[1].Score = 240;
players[1].calculation_algorithm = enhanced_bonus;
players[2].Name = "Caro";
players[2].Score = 89;
players[2].calculation_algorithm = standard_bonus;
players[3].Name = "Andy";
players[3].Score = 38;
players[3].calculation_algorithm = enhanced_bonus;
players[4].Name = "Hugo";
players[4].Score = 600;
players[4].calculation_algorithm = enhanced_bonus;
foreach (Player player in players)
{
PerformCalculationBonus(player);
}
foreach (Player player in players)
{
DisplayPersonalDetails(player);
}
Console.ReadLine();
}
public static void PerformCalculationBonus(Player player)
{
player.Bonus = player.calculation_algorithm(player.Score);
}
public static void DisplayPersonalDetails(Player player)
{
Console.WriteLine(player.Name);
Console.WriteLine(player.Score);
Console.WriteLine(player.Bonus);
Console.WriteLine("---------------");
}
}
}
Anonymous delegates are designed to help you make code more readable by being able to define the behavior of a simple delegate inline in another method. This means that if you're dealing with something that requires a delegate (an event handler, for example), you can define the behavior right in the code rather than creating a dedicated function for it.
In addition, they're the precursor for lambda expressions. Things like LINQ to Objects (any of the methods that operate on IEnumerable<T>) use delegates to perform queries on objects. For example, if you have a collection of strings and you want a query that finds all of them that are five characters long, you can do that with a lambda:
List<string> strings = ...
var query = strings.Where(s => s.Length == 5);
Or you could do it with an anonymous delegate:
var query = strings.Where(delegate(string s) { return s.Length == 5; });
If you didn't have these, your code would look something like this:
var query = strings.Where(IsFiveCharacters);
...
private bool IsFiveCharacters(string input)
{
return input.Length == 5;
}
It's important to realize, though, that lambdas and anonymous delegates are just compiler features. When your code is compiled, it does actually create regular functions like in the last example, but they're hidden and named using characters that are illegal in the language being used. There's a lot of logic that goes around them when doing things like closures (where you access a variable that exists outside of the lambda/anonymous delegate declaration), as well.
The benefit is that you don't have to look somewhere else for the code to do a one-time lookup/change/calculation/whatever. It's a bit annoying to have to add a function (or a whole other class for a function!) you'll only ever use in one place, and then you have to look back later and see what that bit of code was and why it's needed and whether it still is.
With an anonymous delegate, the code is right there in the code that uses it.