Can I expand a string that contains C# literal expressions at runtime
Similar to Mikael answer but using the CSharpCodeProvider:
public static string ParseString(string txt)
{
var provider = new Microsoft.CSharp.CSharpCodeProvider();
var prms = new System.CodeDom.Compiler.CompilerParameters();
prms.GenerateExecutable = false;
prms.GenerateInMemory = true;
var results = provider.CompileAssemblyFromSource(prms, @"
namespace tmp
{
public class tmpClass
{
public static string GetValue()
{
return " + "\"" + txt + "\"" + @";
}
}
}");
System.Reflection.Assembly ass = results.CompiledAssembly;
var method = ass.GetType("tmp.tmpClass").GetMethod("GetValue");
return method.Invoke(null, null) as string;
}
You might be better off using a dictionary of wildcards and just replacing them in the string.
Insert variable values in the middle of a string
You can use string.Format
:
string template = "Hi We have these flights for you: {0}. Which one do you want";
string data = "A, B, C, D";
string message = string.Format(template, data);
You should load template
from your resource file and data
is your runtime values.
Be careful if you're translating to multiple languages, though: in some cases, you'll need different tokens (the {0}
) in different languages.
Dynamic string interpolation
Two suggestions:
DataBinder.Eval
string ReplaceMacro(string value, Job job)
{
return Regex.Replace(value, @"{(?<exp>[^}]+)}", match => {
return (System.Web.UI.DataBinder.Eval(new { Job = job }, match.Groups["exp"].Value) ?? "").ToString();
});
}
Linq.Expression
Use the Dynamic Query class provided in the MSDN LINQSamples:
string ReplaceMacro(string value, Job job)
{
return Regex.Replace(value, @"{(?<exp>[^}]+)}", match => {
var p = Expression.Parameter(typeof(Job), "job");
var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { p }, null, match.Groups["exp"].Value);
return (e.Compile().DynamicInvoke(job) ?? "").ToString();
});
}
In my opinion, the Linq.Expression is more powerful, so if you trust the input string, you can do more interesting things, i.e.:
value = "{job.Name.ToUpper()} job for admin"
return = "TODO job for admin"
How to force a runtime constant to be a compile time constant?
You can't, in general. Anything which involves a method call is not going to be a compile-time constant, as far as the compiler is concerned.
What you can do is express a double
literal using scientific notation though:
public const double AvogadrosNumber = 6.022e-22;
So in this specific case you can write it with no loss of readability.
In other settings, so long as the type is one of the primitive types or decimal
, you can just write out the constant as a literal, and use a comment to explain how you got it. For example:
// Math.Sqrt(Math.PI)
public const double SquareRootOfPi = 1.7724538509055159;
Note that even though method calls can't be used in constant expressions, other operators can. For example:
// This is fine
public const double PiSquared = Math.PI * Math.PI;
// This is invalid
public const double PiSquared = Math.Pow(Math.PI, 2);
See section 7.19 of the C# 5 specification for more details about what is allowed within a constant expression.
Resolving a parameter name at runtime
One way:
static void Main(string[] args)
{
Console.WriteLine("Name is '{0}'", GetName(new {args}));
Console.ReadLine();
}
This code also requires a supporting function:
static string GetName<T>(T item) where T : class
{
var properties = typeof(T).GetProperties();
Enforce.That(properties.Length == 1);
return properties[0].Name;
}
Basically the code works by defining a new Anonymous Type with a single Property consisting of the parameter who's name you want. GetName() then uses reflection to extract the name of that Property.
There are more details here: http://abdullin.com/journal/2008/12/13/how-to-find-out-variable-or-parameter-name-in-c.html
ReferenceEquals working wrong with strings
The first example has a compile time constant "fg"
that is referenced by two variables. Since this is a compile time constant, the two variables reference the one object. The references are equal.
Read into the topic of string interning for more on this behavior. As a starter, consider:
For example, if you assign the same literal string to several variables, the runtime retrieves the same reference to the literal string from the intern pool and assigns it to each variable.
http://msdn.microsoft.com/en-us/library/system.string.intern.aspx
In the second example, only one is a compile time constant, the other is a result of some operations. a
and d
do not reference the same object, so you get the false result from ReferenceEquals
.
Related Topics
Serializable Classes and Dynamic Proxies in Ef - How
How to Parse Dates with a Suffix "Th", "St" or "Nd" on the Day of the Month
How to Derive Xml Element Name from an Attribute Value of a Class Using Annotations
Wcf - Design Parameter Decision
How Are Nullable Types Implemented Under the Hood in .Net
JSON.Net Adding Backslash While Returning JSON Serialized String
Read a Xml (From a String) and Get Some Fields - Problems Reading Xml
How to Tell If a Type Is a "Simple" Type? I.E. Holds a Single Value
Read Big Txt File, Out of Memory Exception
Windows.Forms.Panel 32767 Size Limit
C# Constructing Parameter Query SQL - Like %
Is There a Complete Iequatable Implementation Reference
Microsoft Visual Studio and C#: How to Visually Add Events to Controls
Cannot Resolve Scoped Service from Root Provider .Net Core 2
How to Create Xmlelement Attributes with Prefix
What's the Best Way to Test SQL Server Connection Programmatically