Pass multiple parameters, choose one that's been passed in c# - c#

Calling my method:
fpt.CouttsPositionSection.AssetClassAssets.Add(dataGenerator.GenerateFPTAssetClassAsset(fpt,*different parameter*));
My method:
public FPTAssetClassAsset GenerateFPTAssetClassAsset(FPT fpt, *4 parameters, with different variable names*)
{
FPTStaticDataAssetClassAssetlist = db.FPTStaticDataRatedFinancialAssetBase.OfType<FPTStaticDataAssetClassAsset>().Where(e => e.FORATExcelId == 1).ToList();
var fptdocassets = fpt.CouttsPositionSection.AssetClassAssets.Select(e => e.StaticDataAssetClassAsset).ToList();
var listTemp = FPTStaticDataAssetClassAssetlist.Where(i => !fptdocassets.Contains(i)).ToList();
FPTAssetClassAsset a = new FPTAssetClassAsset();
a.StaticDataAssetClassAsset = listTemp[random.Next(0, listTemp.Count())];
a.Currency = a.StaticDataAssetClassAsset.Currency;
a.Description = a.StaticDataAssetClassAsset.Name + " Descr";
a.Holdings.Add(GenerateFPTRatedFinancialAssetHolding());
FillCommonRateFinancialAssetData(a, fpt);
fpt.UpdateXrates(a.StaticDataAssetClassAsset.CurrencyId);
return a;
}
When i run the method it will be called 4 times with 4 different parameters. If i set 4 optional parameters that's fine, however they all have different variable names. Below the variable name will go between the stars, but i have 4 so is there any way of having the variable change its value or name?
var fptdocassets = fpt.*variable of parameter passed*.AssetClassAssets

I solved this by passing in a string instead, and using the following method to return the object that it matched.
public static object GetPropValue(object src, string propName)
{
return src.GetType().GetProperty(propName).GetValue(src, null);
}

Related

Get name of passed argument in C# method [duplicate]

Let me use the following example to explain my question:
public string ExampleFunction(string Variable) {
return something;
}
string WhatIsMyName = "Hello World";
string Hello = ExampleFunction(WhatIsMyName);
When I pass the variable WhatIsMyName to the ExampleFunction, I want to be able to get a string of the original variable's name. Perhaps something like:
Variable.OriginalName.ToString() // == "WhatIsMyName"
Is there any way to do this?
What you want isn't possible directly but you can use Expressions in C# 3.0:
public void ExampleFunction(Expression<Func<string, string>> f) {
Console.WriteLine((f.Body as MemberExpression).Member.Name);
}
ExampleFunction(x => WhatIsMyName);
Note that this relies on unspecified behaviour and while it does work in Microsoft’s current C# and VB compilers, and in Mono’s C# compiler, there’s no guarantee that this won’t stop working in future versions.
This isn't exactly possible, the way you would want. C# 6.0 they Introduce the nameof Operator which should help improve and simplify the code. The name of operator resolves the name of the variable passed into it.
Usage for your case would look like this:
public string ExampleFunction(string variableName) {
//Construct your log statement using c# 6.0 string interpolation
return $"Error occurred in {variableName}";
}
string WhatIsMyName = "Hello World";
string Hello = ExampleFunction(nameof(WhatIsMyName));
A major benefit is that it is done at compile time,
The nameof expression is a constant. In all cases, nameof(...) is evaluated at compile-time to produce a string. Its argument is not evaluated at runtime, and is considered unreachable code (however it does not emit an "unreachable code" warning).
More information can be found here
Older Version Of C 3.0 and above
To Build on Nawfals answer
GetParameterName2(new { variable });
//Hack to assure compiler warning is generated specifying this method calling conventions
[Obsolete("Note you must use a single parametered AnonymousType When Calling this method")]
public static string GetParameterName<T>(T item) where T : class
{
if (item == null)
return string.Empty;
return typeof(T).GetProperties()[0].Name;
}
I know this post is really old, but since there is now a way in C#10 compiler, I thought I would share so others know.
You can now use CallerArgumentExpressionAttribute as shown
// Will throw argument exception if string IsNullOrEmpty returns true
public static void ValidateNotNullorEmpty(
this string str,
[CallerArgumentExpression("str")]string strName = null
)
{
if (string.IsNullOrEmpty(str))
{
throw new ArgumentException($"'{strName}' cannot be null or empty.", strName);
}
}
Now call with:
param.ValidateNotNullorEmpty();
will throw error: "param cannot be null or empty."
instead of "str cannot be null or empty"
static void Main(string[] args)
{
Console.WriteLine("Name is '{0}'", GetName(new {args}));
Console.ReadLine();
}
static string GetName<T>(T item) where T : class
{
var properties = typeof(T).GetProperties();
Enforce.That(properties.Length == 1);
return properties[0].Name;
}
More details are in this blog post.
Three ways:
1) Something without reflection at all:
GetParameterName1(new { variable });
public static string GetParameterName1<T>(T item) where T : class
{
if (item == null)
return string.Empty;
return item.ToString().TrimStart('{').TrimEnd('}').Split('=')[0].Trim();
}
2) Uses reflection, but this is way faster than other two.
GetParameterName2(new { variable });
public static string GetParameterName2<T>(T item) where T : class
{
if (item == null)
return string.Empty;
return typeof(T).GetProperties()[0].Name;
}
3) The slowest of all, don't use.
GetParameterName3(() => variable);
public static string GetParameterName3<T>(Expression<Func<T>> expr)
{
if (expr == null)
return string.Empty;
return ((MemberExpression)expr.Body).Member.Name;
}
To get a combo parameter name and value, you can extend these methods. Of course its easy to get value if you pass the parameter separately as another argument, but that's inelegant. Instead:
1)
public static string GetParameterInfo1<T>(T item) where T : class
{
if (item == null)
return string.Empty;
var param = item.ToString().TrimStart('{').TrimEnd('}').Split('=');
return "Parameter: '" + param[0].Trim() +
"' = " + param[1].Trim();
}
2)
public static string GetParameterInfo2<T>(T item) where T : class
{
if (item == null)
return string.Empty;
var param = typeof(T).GetProperties()[0];
return "Parameter: '" + param.Name +
"' = " + param.GetValue(item, null);
}
3)
public static string GetParameterInfo3<T>(Expression<Func<T>> expr)
{
if (expr == null)
return string.Empty;
var param = (MemberExpression)expr.Body;
return "Parameter: '" + param.Member.Name +
"' = " + ((FieldInfo)param.Member).GetValue(((ConstantExpression)param.Expression).Value);
}
1 and 2 are of comparable speed now, 3 is again sluggish.
Yes! It is possible. I have been looking for a solution to this for a long time and have finally come up with a hack that solves it (it's a bit nasty). I would not recommend using this as part of your program and I only think it works in debug mode. For me this doesn't matter as I only use it as a debugging tool in my console class so I can do:
int testVar = 1;
bool testBoolVar = True;
myConsole.Writeline(testVar);
myConsole.Writeline(testBoolVar);
the output to the console would be:
testVar: 1
testBoolVar: True
Here is the function I use to do that (not including the wrapping code for my console class.
public Dictionary<string, string> nameOfAlreadyAcessed = new Dictionary<string, string>();
public string nameOf(object obj, int level = 1)
{
StackFrame stackFrame = new StackTrace(true).GetFrame(level);
string fileName = stackFrame.GetFileName();
int lineNumber = stackFrame.GetFileLineNumber();
string uniqueId = fileName + lineNumber;
if (nameOfAlreadyAcessed.ContainsKey(uniqueId))
return nameOfAlreadyAcessed[uniqueId];
else
{
System.IO.StreamReader file = new System.IO.StreamReader(fileName);
for (int i = 0; i < lineNumber - 1; i++)
file.ReadLine();
string varName = file.ReadLine().Split(new char[] { '(', ')' })[1];
nameOfAlreadyAcessed.Add(uniqueId, varName);
return varName;
}
}
Continuing with the Caller* attribute series (i.e CallerMemberName, CallerFilePath and CallerLineNumber), CallerArgumentExpressionAttribute is available since C# Next (more info here).
The following example is inspired by Paul Mcilreavy's The CallerArgumentExpression Attribute in C# 8.0:
public static void ThrowIfNullOrWhitespace(this string self,
[CallerArgumentExpression("self")] string paramName = default)
{
if (self is null)
{
throw new ArgumentNullException(paramName);
}
if (string.IsNullOrWhiteSpace(self))
{
throw new ArgumentOutOfRangeException(paramName, self, "Value cannot be whitespace");
}
}
This would be very useful to do in order to create good exception messages causing people to be able to pinpoint errors better. Line numbers help, but you might not get them in prod, and when you do get them, if there are big statements in code, you typically only get the first line of the whole statement.
For instance, if you call .Value on a nullable that isn't set, you'll get an exception with a failure message, but as this functionality is lacking, you won't see what property was null. If you do this twice in one statement, for instance to set parameters to some method, you won't be able to see what nullable was not set.
Creating code like Verify.NotNull(myvar, nameof(myvar)) is the best workaround I've found so far, but would be great to get rid of the need to add the extra parameter.
No, but whenever you find yourself doing extremely complex things like this, you might want to re-think your solution. Remember that code should be easier to read than it was to write.
System.Environment.StackTrace will give you a string that includes the current call stack. You could parse that to get the information, which includes the variable names for each call.
Well Try this Utility class,
public static class Utility
{
public static Tuple<string, TSource> GetNameAndValue<TSource>(Expression<Func<TSource>> sourceExpression)
{
Tuple<String, TSource> result = null;
Type type = typeof (TSource);
Func<MemberExpression, Tuple<String, TSource>> process = delegate(MemberExpression memberExpression)
{
ConstantExpression constantExpression = (ConstantExpression)memberExpression.Expression;
var name = memberExpression.Member.Name;
var value = ((FieldInfo)memberExpression.Member).GetValue(constantExpression.Value);
return new Tuple<string, TSource>(name, (TSource) value);
};
Expression exception = sourceExpression.Body;
if (exception is MemberExpression)
{
result = process((MemberExpression)sourceExpression.Body);
}
else if (exception is UnaryExpression)
{
UnaryExpression unaryExpression = (UnaryExpression)sourceExpression.Body;
result = process((MemberExpression)unaryExpression.Operand);
}
else
{
throw new Exception("Expression type unknown.");
}
return result;
}
}
And User It Like
/*ToDo : Test Result*/
static void Main(string[] args)
{
/*Test : primivit types*/
long maxNumber = 123123;
Tuple<string, long> longVariable = Utility.GetNameAndValue(() => maxNumber);
string longVariableName = longVariable.Item1;
long longVariableValue = longVariable.Item2;
/*Test : user define types*/
Person aPerson = new Person() { Id = "123", Name = "Roy" };
Tuple<string, Person> personVariable = Utility.GetNameAndValue(() => aPerson);
string personVariableName = personVariable.Item1;
Person personVariableValue = personVariable.Item2;
/*Test : anonymous types*/
var ann = new { Id = "123", Name = "Roy" };
var annVariable = Utility.GetNameAndValue(() => ann);
string annVariableName = annVariable.Item1;
var annVariableValue = annVariable.Item2;
/*Test : Enum tyoes*/
Active isActive = Active.Yes;
Tuple<string, Active> isActiveVariable = Utility.GetNameAndValue(() => isActive);
string isActiveVariableName = isActiveVariable.Item1;
Active isActiveVariableValue = isActiveVariable.Item2;
}
Do this
var myVariable = 123;
myVariable.Named(() => myVariable);
var name = myVariable.Name();
// use name how you like
or naming in code by hand
var myVariable = 123.Named("my variable");
var name = myVariable.Name();
using this class
public static class ObjectInstanceExtensions
{
private static Dictionary<object, string> namedInstances = new Dictionary<object, string>();
public static void Named<T>(this T instance, Expression<Func<T>> expressionContainingOnlyYourInstance)
{
var name = ((MemberExpression)expressionContainingOnlyYourInstance.Body).Member.Name;
instance.Named(name);
}
public static T Named<T>(this T instance, string named)
{
if (namedInstances.ContainsKey(instance)) namedInstances[instance] = named;
else namedInstances.Add(instance, named);
return instance;
}
public static string Name<T>(this T instance)
{
if (namedInstances.ContainsKey(instance)) return namedInstances[instance];
throw new NotImplementedException("object has not been named");
}
}
Code tested and most elegant I can come up with.
Thanks for all the responses. I guess I'll just have to go with what I'm doing now.
For those who wanted to know why I asked the above question. I have the following function:
string sMessages(ArrayList aMessages, String sType) {
string sReturn = String.Empty;
if (aMessages.Count > 0) {
sReturn += "<p class=\"" + sType + "\">";
for (int i = 0; i < aMessages.Count; i++) {
sReturn += aMessages[i] + "<br />";
}
sReturn += "</p>";
}
return sReturn;
}
I send it an array of error messages and a css class which is then returned as a string for a webpage.
Every time I call this function, I have to define sType. Something like:
output += sMessages(aErrors, "errors");
As you can see, my variables is called aErrors and my css class is called errors. I was hoping my cold could figure out what class to use based on the variable name I sent it.
Again, thanks for all the responses.
thanks to visual studio 2022 , you can use this
function
public void showname(dynamic obj) {
obj.GetType().GetProperties().ToList().ForEach(state => {
NameAndValue($"{state.Name}:{state.GetValue(obj, null).ToString()}");
});
}
to use
var myname = "dddd";
showname(new { myname });
The short answer is no ... unless you are really really motivated.
The only way to do this would be via reflection and stack walking. You would have to get a stack frame, work out whereabouts in the calling function you where invoked from and then using the CodeDOM try to find the right part of the tree to see what the expression was.
For example, what if the invocation was ExampleFunction("a" + "b")?
No. A reference to your string variable gets passed to the funcion--there isn't any inherent metadeta about it included. Even reflection wouldn't get you out of the woods here--working backwards from a single reference type doesn't get you enough info to do what you need to do.
Better go back to the drawing board on this one!
rp
You could use reflection to get all the properties of an object, than loop through it, and get the value of the property where the name (of the property) matches the passed in parameter.
Well had a bit of look. of course you can't use any Type information.
Also, the name of a local variable is not available at runtime
because their names are not compiled into the assembly's metadata.
GateKiller, what's wrong with my workaround? You could rewrite your function trivially to use it (I've taken the liberty to improve the function on the fly):
static string sMessages(Expression<Func<List<string>>> aMessages) {
var messages = aMessages.Compile()();
if (messages.Count == 0) {
return "";
}
StringBuilder ret = new StringBuilder();
string sType = ((MemberExpression)aMessages.Body).Member.Name;
ret.AppendFormat("<p class=\"{0}\">", sType);
foreach (string msg in messages) {
ret.Append(msg);
ret.Append("<br />");
}
ret.Append("</p>");
return ret.ToString();
}
Call it like this:
var errors = new List<string>() { "Hi", "foo" };
var ret = sMessages(() => errors);
A way to get it can be reading the code file and splitting it with comma and parenthesis...
var trace = new StackTrace(true).GetFrame(1);
var line = File.ReadAllLines(trace.GetFileName())[trace.GetFileLineNumber()];
var argumentNames = line.Split(new[] { ",", "(", ")", ";" },
StringSplitOptions.TrimEntries)
.Where(x => x.Length > 0)
.Skip(1).ToList();
Extending on the accepted answer for this question, here is how you'd do it with #nullable enable source files:
internal static class StringExtensions
{
public static void ValidateNotNull(
[NotNull] this string? theString,
[CallerArgumentExpression("theString")] string? theName = default)
{
if (theString is null)
{
throw new ArgumentException($"'{theName}' cannot be null.", theName);
}
}
public static void ValidateNotNullOrEmpty(
[NotNull] this string? theString,
[CallerArgumentExpression("theString")] string? theName = default)
{
if (string.IsNullOrEmpty(theString))
{
throw new ArgumentException($"'{theName}' cannot be null or empty.", theName);
}
}
public static void ValidateNotNullOrWhitespace(
[NotNull] this string? theString,
[CallerArgumentExpression("theString")] string? theName = default)
{
if (string.IsNullOrWhiteSpace(theString))
{
throw new ArgumentException($"'{theName}' cannot be null or whitespace", theName);
}
}
}
What's nice about this code is that it uses [NotNull] attribute, so the static analysis will cooperate:
If I understand you correctly, you want the string "WhatIsMyName" to appear inside the Hello string.
string Hello = ExampleFunction(WhatIsMyName);
If the use case is that it increases the reusability of ExampleFunction and that Hello shall contain something like "Hello, Peter (from WhatIsMyName)", then I think a solution would be to expand the ExampleFunction to accept:
string Hello = ExampleFunction(WhatIsMyName,nameof(WhatIsMyName));
So that the name is passed as a separate string. Yes, it is not exactly what you asked and you will have to type it twice. But it is refactor safe, readable, does not use the debug interface and the chance of Error is minimal because they appear together in the consuming code.
string Hello1 = ExampleFunction(WhatIsMyName,nameof(WhatIsMyName));
string Hello2 = ExampleFunction(SomebodyElse,nameof(SomebodyElse));
string Hello3 = ExampleFunction(HerName,nameof(HerName));
No. I don't think so.
The variable name that you use is for your convenience and readability. The compiler doesn't need it & just chucks it out if I'm not mistaken.
If it helps, you could define a new class called NamedParameter with attributes Name and Param. You then pass this object around as parameters.

Get both name and type of a single passed argument? [duplicate]

Let me use the following example to explain my question:
public string ExampleFunction(string Variable) {
return something;
}
string WhatIsMyName = "Hello World";
string Hello = ExampleFunction(WhatIsMyName);
When I pass the variable WhatIsMyName to the ExampleFunction, I want to be able to get a string of the original variable's name. Perhaps something like:
Variable.OriginalName.ToString() // == "WhatIsMyName"
Is there any way to do this?
What you want isn't possible directly but you can use Expressions in C# 3.0:
public void ExampleFunction(Expression<Func<string, string>> f) {
Console.WriteLine((f.Body as MemberExpression).Member.Name);
}
ExampleFunction(x => WhatIsMyName);
Note that this relies on unspecified behaviour and while it does work in Microsoft’s current C# and VB compilers, and in Mono’s C# compiler, there’s no guarantee that this won’t stop working in future versions.
This isn't exactly possible, the way you would want. C# 6.0 they Introduce the nameof Operator which should help improve and simplify the code. The name of operator resolves the name of the variable passed into it.
Usage for your case would look like this:
public string ExampleFunction(string variableName) {
//Construct your log statement using c# 6.0 string interpolation
return $"Error occurred in {variableName}";
}
string WhatIsMyName = "Hello World";
string Hello = ExampleFunction(nameof(WhatIsMyName));
A major benefit is that it is done at compile time,
The nameof expression is a constant. In all cases, nameof(...) is evaluated at compile-time to produce a string. Its argument is not evaluated at runtime, and is considered unreachable code (however it does not emit an "unreachable code" warning).
More information can be found here
Older Version Of C 3.0 and above
To Build on Nawfals answer
GetParameterName2(new { variable });
//Hack to assure compiler warning is generated specifying this method calling conventions
[Obsolete("Note you must use a single parametered AnonymousType When Calling this method")]
public static string GetParameterName<T>(T item) where T : class
{
if (item == null)
return string.Empty;
return typeof(T).GetProperties()[0].Name;
}
I know this post is really old, but since there is now a way in C#10 compiler, I thought I would share so others know.
You can now use CallerArgumentExpressionAttribute as shown
// Will throw argument exception if string IsNullOrEmpty returns true
public static void ValidateNotNullorEmpty(
this string str,
[CallerArgumentExpression("str")]string strName = null
)
{
if (string.IsNullOrEmpty(str))
{
throw new ArgumentException($"'{strName}' cannot be null or empty.", strName);
}
}
Now call with:
param.ValidateNotNullorEmpty();
will throw error: "param cannot be null or empty."
instead of "str cannot be null or empty"
static void Main(string[] args)
{
Console.WriteLine("Name is '{0}'", GetName(new {args}));
Console.ReadLine();
}
static string GetName<T>(T item) where T : class
{
var properties = typeof(T).GetProperties();
Enforce.That(properties.Length == 1);
return properties[0].Name;
}
More details are in this blog post.
Three ways:
1) Something without reflection at all:
GetParameterName1(new { variable });
public static string GetParameterName1<T>(T item) where T : class
{
if (item == null)
return string.Empty;
return item.ToString().TrimStart('{').TrimEnd('}').Split('=')[0].Trim();
}
2) Uses reflection, but this is way faster than other two.
GetParameterName2(new { variable });
public static string GetParameterName2<T>(T item) where T : class
{
if (item == null)
return string.Empty;
return typeof(T).GetProperties()[0].Name;
}
3) The slowest of all, don't use.
GetParameterName3(() => variable);
public static string GetParameterName3<T>(Expression<Func<T>> expr)
{
if (expr == null)
return string.Empty;
return ((MemberExpression)expr.Body).Member.Name;
}
To get a combo parameter name and value, you can extend these methods. Of course its easy to get value if you pass the parameter separately as another argument, but that's inelegant. Instead:
1)
public static string GetParameterInfo1<T>(T item) where T : class
{
if (item == null)
return string.Empty;
var param = item.ToString().TrimStart('{').TrimEnd('}').Split('=');
return "Parameter: '" + param[0].Trim() +
"' = " + param[1].Trim();
}
2)
public static string GetParameterInfo2<T>(T item) where T : class
{
if (item == null)
return string.Empty;
var param = typeof(T).GetProperties()[0];
return "Parameter: '" + param.Name +
"' = " + param.GetValue(item, null);
}
3)
public static string GetParameterInfo3<T>(Expression<Func<T>> expr)
{
if (expr == null)
return string.Empty;
var param = (MemberExpression)expr.Body;
return "Parameter: '" + param.Member.Name +
"' = " + ((FieldInfo)param.Member).GetValue(((ConstantExpression)param.Expression).Value);
}
1 and 2 are of comparable speed now, 3 is again sluggish.
Yes! It is possible. I have been looking for a solution to this for a long time and have finally come up with a hack that solves it (it's a bit nasty). I would not recommend using this as part of your program and I only think it works in debug mode. For me this doesn't matter as I only use it as a debugging tool in my console class so I can do:
int testVar = 1;
bool testBoolVar = True;
myConsole.Writeline(testVar);
myConsole.Writeline(testBoolVar);
the output to the console would be:
testVar: 1
testBoolVar: True
Here is the function I use to do that (not including the wrapping code for my console class.
public Dictionary<string, string> nameOfAlreadyAcessed = new Dictionary<string, string>();
public string nameOf(object obj, int level = 1)
{
StackFrame stackFrame = new StackTrace(true).GetFrame(level);
string fileName = stackFrame.GetFileName();
int lineNumber = stackFrame.GetFileLineNumber();
string uniqueId = fileName + lineNumber;
if (nameOfAlreadyAcessed.ContainsKey(uniqueId))
return nameOfAlreadyAcessed[uniqueId];
else
{
System.IO.StreamReader file = new System.IO.StreamReader(fileName);
for (int i = 0; i < lineNumber - 1; i++)
file.ReadLine();
string varName = file.ReadLine().Split(new char[] { '(', ')' })[1];
nameOfAlreadyAcessed.Add(uniqueId, varName);
return varName;
}
}
Continuing with the Caller* attribute series (i.e CallerMemberName, CallerFilePath and CallerLineNumber), CallerArgumentExpressionAttribute is available since C# Next (more info here).
The following example is inspired by Paul Mcilreavy's The CallerArgumentExpression Attribute in C# 8.0:
public static void ThrowIfNullOrWhitespace(this string self,
[CallerArgumentExpression("self")] string paramName = default)
{
if (self is null)
{
throw new ArgumentNullException(paramName);
}
if (string.IsNullOrWhiteSpace(self))
{
throw new ArgumentOutOfRangeException(paramName, self, "Value cannot be whitespace");
}
}
This would be very useful to do in order to create good exception messages causing people to be able to pinpoint errors better. Line numbers help, but you might not get them in prod, and when you do get them, if there are big statements in code, you typically only get the first line of the whole statement.
For instance, if you call .Value on a nullable that isn't set, you'll get an exception with a failure message, but as this functionality is lacking, you won't see what property was null. If you do this twice in one statement, for instance to set parameters to some method, you won't be able to see what nullable was not set.
Creating code like Verify.NotNull(myvar, nameof(myvar)) is the best workaround I've found so far, but would be great to get rid of the need to add the extra parameter.
No, but whenever you find yourself doing extremely complex things like this, you might want to re-think your solution. Remember that code should be easier to read than it was to write.
System.Environment.StackTrace will give you a string that includes the current call stack. You could parse that to get the information, which includes the variable names for each call.
Well Try this Utility class,
public static class Utility
{
public static Tuple<string, TSource> GetNameAndValue<TSource>(Expression<Func<TSource>> sourceExpression)
{
Tuple<String, TSource> result = null;
Type type = typeof (TSource);
Func<MemberExpression, Tuple<String, TSource>> process = delegate(MemberExpression memberExpression)
{
ConstantExpression constantExpression = (ConstantExpression)memberExpression.Expression;
var name = memberExpression.Member.Name;
var value = ((FieldInfo)memberExpression.Member).GetValue(constantExpression.Value);
return new Tuple<string, TSource>(name, (TSource) value);
};
Expression exception = sourceExpression.Body;
if (exception is MemberExpression)
{
result = process((MemberExpression)sourceExpression.Body);
}
else if (exception is UnaryExpression)
{
UnaryExpression unaryExpression = (UnaryExpression)sourceExpression.Body;
result = process((MemberExpression)unaryExpression.Operand);
}
else
{
throw new Exception("Expression type unknown.");
}
return result;
}
}
And User It Like
/*ToDo : Test Result*/
static void Main(string[] args)
{
/*Test : primivit types*/
long maxNumber = 123123;
Tuple<string, long> longVariable = Utility.GetNameAndValue(() => maxNumber);
string longVariableName = longVariable.Item1;
long longVariableValue = longVariable.Item2;
/*Test : user define types*/
Person aPerson = new Person() { Id = "123", Name = "Roy" };
Tuple<string, Person> personVariable = Utility.GetNameAndValue(() => aPerson);
string personVariableName = personVariable.Item1;
Person personVariableValue = personVariable.Item2;
/*Test : anonymous types*/
var ann = new { Id = "123", Name = "Roy" };
var annVariable = Utility.GetNameAndValue(() => ann);
string annVariableName = annVariable.Item1;
var annVariableValue = annVariable.Item2;
/*Test : Enum tyoes*/
Active isActive = Active.Yes;
Tuple<string, Active> isActiveVariable = Utility.GetNameAndValue(() => isActive);
string isActiveVariableName = isActiveVariable.Item1;
Active isActiveVariableValue = isActiveVariable.Item2;
}
Do this
var myVariable = 123;
myVariable.Named(() => myVariable);
var name = myVariable.Name();
// use name how you like
or naming in code by hand
var myVariable = 123.Named("my variable");
var name = myVariable.Name();
using this class
public static class ObjectInstanceExtensions
{
private static Dictionary<object, string> namedInstances = new Dictionary<object, string>();
public static void Named<T>(this T instance, Expression<Func<T>> expressionContainingOnlyYourInstance)
{
var name = ((MemberExpression)expressionContainingOnlyYourInstance.Body).Member.Name;
instance.Named(name);
}
public static T Named<T>(this T instance, string named)
{
if (namedInstances.ContainsKey(instance)) namedInstances[instance] = named;
else namedInstances.Add(instance, named);
return instance;
}
public static string Name<T>(this T instance)
{
if (namedInstances.ContainsKey(instance)) return namedInstances[instance];
throw new NotImplementedException("object has not been named");
}
}
Code tested and most elegant I can come up with.
Thanks for all the responses. I guess I'll just have to go with what I'm doing now.
For those who wanted to know why I asked the above question. I have the following function:
string sMessages(ArrayList aMessages, String sType) {
string sReturn = String.Empty;
if (aMessages.Count > 0) {
sReturn += "<p class=\"" + sType + "\">";
for (int i = 0; i < aMessages.Count; i++) {
sReturn += aMessages[i] + "<br />";
}
sReturn += "</p>";
}
return sReturn;
}
I send it an array of error messages and a css class which is then returned as a string for a webpage.
Every time I call this function, I have to define sType. Something like:
output += sMessages(aErrors, "errors");
As you can see, my variables is called aErrors and my css class is called errors. I was hoping my cold could figure out what class to use based on the variable name I sent it.
Again, thanks for all the responses.
thanks to visual studio 2022 , you can use this
function
public void showname(dynamic obj) {
obj.GetType().GetProperties().ToList().ForEach(state => {
NameAndValue($"{state.Name}:{state.GetValue(obj, null).ToString()}");
});
}
to use
var myname = "dddd";
showname(new { myname });
The short answer is no ... unless you are really really motivated.
The only way to do this would be via reflection and stack walking. You would have to get a stack frame, work out whereabouts in the calling function you where invoked from and then using the CodeDOM try to find the right part of the tree to see what the expression was.
For example, what if the invocation was ExampleFunction("a" + "b")?
No. A reference to your string variable gets passed to the funcion--there isn't any inherent metadeta about it included. Even reflection wouldn't get you out of the woods here--working backwards from a single reference type doesn't get you enough info to do what you need to do.
Better go back to the drawing board on this one!
rp
You could use reflection to get all the properties of an object, than loop through it, and get the value of the property where the name (of the property) matches the passed in parameter.
Well had a bit of look. of course you can't use any Type information.
Also, the name of a local variable is not available at runtime
because their names are not compiled into the assembly's metadata.
GateKiller, what's wrong with my workaround? You could rewrite your function trivially to use it (I've taken the liberty to improve the function on the fly):
static string sMessages(Expression<Func<List<string>>> aMessages) {
var messages = aMessages.Compile()();
if (messages.Count == 0) {
return "";
}
StringBuilder ret = new StringBuilder();
string sType = ((MemberExpression)aMessages.Body).Member.Name;
ret.AppendFormat("<p class=\"{0}\">", sType);
foreach (string msg in messages) {
ret.Append(msg);
ret.Append("<br />");
}
ret.Append("</p>");
return ret.ToString();
}
Call it like this:
var errors = new List<string>() { "Hi", "foo" };
var ret = sMessages(() => errors);
A way to get it can be reading the code file and splitting it with comma and parenthesis...
var trace = new StackTrace(true).GetFrame(1);
var line = File.ReadAllLines(trace.GetFileName())[trace.GetFileLineNumber()];
var argumentNames = line.Split(new[] { ",", "(", ")", ";" },
StringSplitOptions.TrimEntries)
.Where(x => x.Length > 0)
.Skip(1).ToList();
Extending on the accepted answer for this question, here is how you'd do it with #nullable enable source files:
internal static class StringExtensions
{
public static void ValidateNotNull(
[NotNull] this string? theString,
[CallerArgumentExpression("theString")] string? theName = default)
{
if (theString is null)
{
throw new ArgumentException($"'{theName}' cannot be null.", theName);
}
}
public static void ValidateNotNullOrEmpty(
[NotNull] this string? theString,
[CallerArgumentExpression("theString")] string? theName = default)
{
if (string.IsNullOrEmpty(theString))
{
throw new ArgumentException($"'{theName}' cannot be null or empty.", theName);
}
}
public static void ValidateNotNullOrWhitespace(
[NotNull] this string? theString,
[CallerArgumentExpression("theString")] string? theName = default)
{
if (string.IsNullOrWhiteSpace(theString))
{
throw new ArgumentException($"'{theName}' cannot be null or whitespace", theName);
}
}
}
What's nice about this code is that it uses [NotNull] attribute, so the static analysis will cooperate:
If I understand you correctly, you want the string "WhatIsMyName" to appear inside the Hello string.
string Hello = ExampleFunction(WhatIsMyName);
If the use case is that it increases the reusability of ExampleFunction and that Hello shall contain something like "Hello, Peter (from WhatIsMyName)", then I think a solution would be to expand the ExampleFunction to accept:
string Hello = ExampleFunction(WhatIsMyName,nameof(WhatIsMyName));
So that the name is passed as a separate string. Yes, it is not exactly what you asked and you will have to type it twice. But it is refactor safe, readable, does not use the debug interface and the chance of Error is minimal because they appear together in the consuming code.
string Hello1 = ExampleFunction(WhatIsMyName,nameof(WhatIsMyName));
string Hello2 = ExampleFunction(SomebodyElse,nameof(SomebodyElse));
string Hello3 = ExampleFunction(HerName,nameof(HerName));
No. I don't think so.
The variable name that you use is for your convenience and readability. The compiler doesn't need it & just chucks it out if I'm not mistaken.
If it helps, you could define a new class called NamedParameter with attributes Name and Param. You then pass this object around as parameters.

How can I get the string of a variable name passed by reference? [duplicate]

Let me use the following example to explain my question:
public string ExampleFunction(string Variable) {
return something;
}
string WhatIsMyName = "Hello World";
string Hello = ExampleFunction(WhatIsMyName);
When I pass the variable WhatIsMyName to the ExampleFunction, I want to be able to get a string of the original variable's name. Perhaps something like:
Variable.OriginalName.ToString() // == "WhatIsMyName"
Is there any way to do this?
What you want isn't possible directly but you can use Expressions in C# 3.0:
public void ExampleFunction(Expression<Func<string, string>> f) {
Console.WriteLine((f.Body as MemberExpression).Member.Name);
}
ExampleFunction(x => WhatIsMyName);
Note that this relies on unspecified behaviour and while it does work in Microsoft’s current C# and VB compilers, and in Mono’s C# compiler, there’s no guarantee that this won’t stop working in future versions.
This isn't exactly possible, the way you would want. C# 6.0 they Introduce the nameof Operator which should help improve and simplify the code. The name of operator resolves the name of the variable passed into it.
Usage for your case would look like this:
public string ExampleFunction(string variableName) {
//Construct your log statement using c# 6.0 string interpolation
return $"Error occurred in {variableName}";
}
string WhatIsMyName = "Hello World";
string Hello = ExampleFunction(nameof(WhatIsMyName));
A major benefit is that it is done at compile time,
The nameof expression is a constant. In all cases, nameof(...) is evaluated at compile-time to produce a string. Its argument is not evaluated at runtime, and is considered unreachable code (however it does not emit an "unreachable code" warning).
More information can be found here
Older Version Of C 3.0 and above
To Build on Nawfals answer
GetParameterName2(new { variable });
//Hack to assure compiler warning is generated specifying this method calling conventions
[Obsolete("Note you must use a single parametered AnonymousType When Calling this method")]
public static string GetParameterName<T>(T item) where T : class
{
if (item == null)
return string.Empty;
return typeof(T).GetProperties()[0].Name;
}
I know this post is really old, but since there is now a way in C#10 compiler, I thought I would share so others know.
You can now use CallerArgumentExpressionAttribute as shown
// Will throw argument exception if string IsNullOrEmpty returns true
public static void ValidateNotNullorEmpty(
this string str,
[CallerArgumentExpression("str")]string strName = null
)
{
if (string.IsNullOrEmpty(str))
{
throw new ArgumentException($"'{strName}' cannot be null or empty.", strName);
}
}
Now call with:
param.ValidateNotNullorEmpty();
will throw error: "param cannot be null or empty."
instead of "str cannot be null or empty"
static void Main(string[] args)
{
Console.WriteLine("Name is '{0}'", GetName(new {args}));
Console.ReadLine();
}
static string GetName<T>(T item) where T : class
{
var properties = typeof(T).GetProperties();
Enforce.That(properties.Length == 1);
return properties[0].Name;
}
More details are in this blog post.
Three ways:
1) Something without reflection at all:
GetParameterName1(new { variable });
public static string GetParameterName1<T>(T item) where T : class
{
if (item == null)
return string.Empty;
return item.ToString().TrimStart('{').TrimEnd('}').Split('=')[0].Trim();
}
2) Uses reflection, but this is way faster than other two.
GetParameterName2(new { variable });
public static string GetParameterName2<T>(T item) where T : class
{
if (item == null)
return string.Empty;
return typeof(T).GetProperties()[0].Name;
}
3) The slowest of all, don't use.
GetParameterName3(() => variable);
public static string GetParameterName3<T>(Expression<Func<T>> expr)
{
if (expr == null)
return string.Empty;
return ((MemberExpression)expr.Body).Member.Name;
}
To get a combo parameter name and value, you can extend these methods. Of course its easy to get value if you pass the parameter separately as another argument, but that's inelegant. Instead:
1)
public static string GetParameterInfo1<T>(T item) where T : class
{
if (item == null)
return string.Empty;
var param = item.ToString().TrimStart('{').TrimEnd('}').Split('=');
return "Parameter: '" + param[0].Trim() +
"' = " + param[1].Trim();
}
2)
public static string GetParameterInfo2<T>(T item) where T : class
{
if (item == null)
return string.Empty;
var param = typeof(T).GetProperties()[0];
return "Parameter: '" + param.Name +
"' = " + param.GetValue(item, null);
}
3)
public static string GetParameterInfo3<T>(Expression<Func<T>> expr)
{
if (expr == null)
return string.Empty;
var param = (MemberExpression)expr.Body;
return "Parameter: '" + param.Member.Name +
"' = " + ((FieldInfo)param.Member).GetValue(((ConstantExpression)param.Expression).Value);
}
1 and 2 are of comparable speed now, 3 is again sluggish.
Yes! It is possible. I have been looking for a solution to this for a long time and have finally come up with a hack that solves it (it's a bit nasty). I would not recommend using this as part of your program and I only think it works in debug mode. For me this doesn't matter as I only use it as a debugging tool in my console class so I can do:
int testVar = 1;
bool testBoolVar = True;
myConsole.Writeline(testVar);
myConsole.Writeline(testBoolVar);
the output to the console would be:
testVar: 1
testBoolVar: True
Here is the function I use to do that (not including the wrapping code for my console class.
public Dictionary<string, string> nameOfAlreadyAcessed = new Dictionary<string, string>();
public string nameOf(object obj, int level = 1)
{
StackFrame stackFrame = new StackTrace(true).GetFrame(level);
string fileName = stackFrame.GetFileName();
int lineNumber = stackFrame.GetFileLineNumber();
string uniqueId = fileName + lineNumber;
if (nameOfAlreadyAcessed.ContainsKey(uniqueId))
return nameOfAlreadyAcessed[uniqueId];
else
{
System.IO.StreamReader file = new System.IO.StreamReader(fileName);
for (int i = 0; i < lineNumber - 1; i++)
file.ReadLine();
string varName = file.ReadLine().Split(new char[] { '(', ')' })[1];
nameOfAlreadyAcessed.Add(uniqueId, varName);
return varName;
}
}
Continuing with the Caller* attribute series (i.e CallerMemberName, CallerFilePath and CallerLineNumber), CallerArgumentExpressionAttribute is available since C# Next (more info here).
The following example is inspired by Paul Mcilreavy's The CallerArgumentExpression Attribute in C# 8.0:
public static void ThrowIfNullOrWhitespace(this string self,
[CallerArgumentExpression("self")] string paramName = default)
{
if (self is null)
{
throw new ArgumentNullException(paramName);
}
if (string.IsNullOrWhiteSpace(self))
{
throw new ArgumentOutOfRangeException(paramName, self, "Value cannot be whitespace");
}
}
This would be very useful to do in order to create good exception messages causing people to be able to pinpoint errors better. Line numbers help, but you might not get them in prod, and when you do get them, if there are big statements in code, you typically only get the first line of the whole statement.
For instance, if you call .Value on a nullable that isn't set, you'll get an exception with a failure message, but as this functionality is lacking, you won't see what property was null. If you do this twice in one statement, for instance to set parameters to some method, you won't be able to see what nullable was not set.
Creating code like Verify.NotNull(myvar, nameof(myvar)) is the best workaround I've found so far, but would be great to get rid of the need to add the extra parameter.
No, but whenever you find yourself doing extremely complex things like this, you might want to re-think your solution. Remember that code should be easier to read than it was to write.
System.Environment.StackTrace will give you a string that includes the current call stack. You could parse that to get the information, which includes the variable names for each call.
Well Try this Utility class,
public static class Utility
{
public static Tuple<string, TSource> GetNameAndValue<TSource>(Expression<Func<TSource>> sourceExpression)
{
Tuple<String, TSource> result = null;
Type type = typeof (TSource);
Func<MemberExpression, Tuple<String, TSource>> process = delegate(MemberExpression memberExpression)
{
ConstantExpression constantExpression = (ConstantExpression)memberExpression.Expression;
var name = memberExpression.Member.Name;
var value = ((FieldInfo)memberExpression.Member).GetValue(constantExpression.Value);
return new Tuple<string, TSource>(name, (TSource) value);
};
Expression exception = sourceExpression.Body;
if (exception is MemberExpression)
{
result = process((MemberExpression)sourceExpression.Body);
}
else if (exception is UnaryExpression)
{
UnaryExpression unaryExpression = (UnaryExpression)sourceExpression.Body;
result = process((MemberExpression)unaryExpression.Operand);
}
else
{
throw new Exception("Expression type unknown.");
}
return result;
}
}
And User It Like
/*ToDo : Test Result*/
static void Main(string[] args)
{
/*Test : primivit types*/
long maxNumber = 123123;
Tuple<string, long> longVariable = Utility.GetNameAndValue(() => maxNumber);
string longVariableName = longVariable.Item1;
long longVariableValue = longVariable.Item2;
/*Test : user define types*/
Person aPerson = new Person() { Id = "123", Name = "Roy" };
Tuple<string, Person> personVariable = Utility.GetNameAndValue(() => aPerson);
string personVariableName = personVariable.Item1;
Person personVariableValue = personVariable.Item2;
/*Test : anonymous types*/
var ann = new { Id = "123", Name = "Roy" };
var annVariable = Utility.GetNameAndValue(() => ann);
string annVariableName = annVariable.Item1;
var annVariableValue = annVariable.Item2;
/*Test : Enum tyoes*/
Active isActive = Active.Yes;
Tuple<string, Active> isActiveVariable = Utility.GetNameAndValue(() => isActive);
string isActiveVariableName = isActiveVariable.Item1;
Active isActiveVariableValue = isActiveVariable.Item2;
}
Do this
var myVariable = 123;
myVariable.Named(() => myVariable);
var name = myVariable.Name();
// use name how you like
or naming in code by hand
var myVariable = 123.Named("my variable");
var name = myVariable.Name();
using this class
public static class ObjectInstanceExtensions
{
private static Dictionary<object, string> namedInstances = new Dictionary<object, string>();
public static void Named<T>(this T instance, Expression<Func<T>> expressionContainingOnlyYourInstance)
{
var name = ((MemberExpression)expressionContainingOnlyYourInstance.Body).Member.Name;
instance.Named(name);
}
public static T Named<T>(this T instance, string named)
{
if (namedInstances.ContainsKey(instance)) namedInstances[instance] = named;
else namedInstances.Add(instance, named);
return instance;
}
public static string Name<T>(this T instance)
{
if (namedInstances.ContainsKey(instance)) return namedInstances[instance];
throw new NotImplementedException("object has not been named");
}
}
Code tested and most elegant I can come up with.
Thanks for all the responses. I guess I'll just have to go with what I'm doing now.
For those who wanted to know why I asked the above question. I have the following function:
string sMessages(ArrayList aMessages, String sType) {
string sReturn = String.Empty;
if (aMessages.Count > 0) {
sReturn += "<p class=\"" + sType + "\">";
for (int i = 0; i < aMessages.Count; i++) {
sReturn += aMessages[i] + "<br />";
}
sReturn += "</p>";
}
return sReturn;
}
I send it an array of error messages and a css class which is then returned as a string for a webpage.
Every time I call this function, I have to define sType. Something like:
output += sMessages(aErrors, "errors");
As you can see, my variables is called aErrors and my css class is called errors. I was hoping my cold could figure out what class to use based on the variable name I sent it.
Again, thanks for all the responses.
thanks to visual studio 2022 , you can use this
function
public void showname(dynamic obj) {
obj.GetType().GetProperties().ToList().ForEach(state => {
NameAndValue($"{state.Name}:{state.GetValue(obj, null).ToString()}");
});
}
to use
var myname = "dddd";
showname(new { myname });
The short answer is no ... unless you are really really motivated.
The only way to do this would be via reflection and stack walking. You would have to get a stack frame, work out whereabouts in the calling function you where invoked from and then using the CodeDOM try to find the right part of the tree to see what the expression was.
For example, what if the invocation was ExampleFunction("a" + "b")?
No. A reference to your string variable gets passed to the funcion--there isn't any inherent metadeta about it included. Even reflection wouldn't get you out of the woods here--working backwards from a single reference type doesn't get you enough info to do what you need to do.
Better go back to the drawing board on this one!
rp
You could use reflection to get all the properties of an object, than loop through it, and get the value of the property where the name (of the property) matches the passed in parameter.
Well had a bit of look. of course you can't use any Type information.
Also, the name of a local variable is not available at runtime
because their names are not compiled into the assembly's metadata.
GateKiller, what's wrong with my workaround? You could rewrite your function trivially to use it (I've taken the liberty to improve the function on the fly):
static string sMessages(Expression<Func<List<string>>> aMessages) {
var messages = aMessages.Compile()();
if (messages.Count == 0) {
return "";
}
StringBuilder ret = new StringBuilder();
string sType = ((MemberExpression)aMessages.Body).Member.Name;
ret.AppendFormat("<p class=\"{0}\">", sType);
foreach (string msg in messages) {
ret.Append(msg);
ret.Append("<br />");
}
ret.Append("</p>");
return ret.ToString();
}
Call it like this:
var errors = new List<string>() { "Hi", "foo" };
var ret = sMessages(() => errors);
A way to get it can be reading the code file and splitting it with comma and parenthesis...
var trace = new StackTrace(true).GetFrame(1);
var line = File.ReadAllLines(trace.GetFileName())[trace.GetFileLineNumber()];
var argumentNames = line.Split(new[] { ",", "(", ")", ";" },
StringSplitOptions.TrimEntries)
.Where(x => x.Length > 0)
.Skip(1).ToList();
Extending on the accepted answer for this question, here is how you'd do it with #nullable enable source files:
internal static class StringExtensions
{
public static void ValidateNotNull(
[NotNull] this string? theString,
[CallerArgumentExpression("theString")] string? theName = default)
{
if (theString is null)
{
throw new ArgumentException($"'{theName}' cannot be null.", theName);
}
}
public static void ValidateNotNullOrEmpty(
[NotNull] this string? theString,
[CallerArgumentExpression("theString")] string? theName = default)
{
if (string.IsNullOrEmpty(theString))
{
throw new ArgumentException($"'{theName}' cannot be null or empty.", theName);
}
}
public static void ValidateNotNullOrWhitespace(
[NotNull] this string? theString,
[CallerArgumentExpression("theString")] string? theName = default)
{
if (string.IsNullOrWhiteSpace(theString))
{
throw new ArgumentException($"'{theName}' cannot be null or whitespace", theName);
}
}
}
What's nice about this code is that it uses [NotNull] attribute, so the static analysis will cooperate:
If I understand you correctly, you want the string "WhatIsMyName" to appear inside the Hello string.
string Hello = ExampleFunction(WhatIsMyName);
If the use case is that it increases the reusability of ExampleFunction and that Hello shall contain something like "Hello, Peter (from WhatIsMyName)", then I think a solution would be to expand the ExampleFunction to accept:
string Hello = ExampleFunction(WhatIsMyName,nameof(WhatIsMyName));
So that the name is passed as a separate string. Yes, it is not exactly what you asked and you will have to type it twice. But it is refactor safe, readable, does not use the debug interface and the chance of Error is minimal because they appear together in the consuming code.
string Hello1 = ExampleFunction(WhatIsMyName,nameof(WhatIsMyName));
string Hello2 = ExampleFunction(SomebodyElse,nameof(SomebodyElse));
string Hello3 = ExampleFunction(HerName,nameof(HerName));
No. I don't think so.
The variable name that you use is for your convenience and readability. The compiler doesn't need it & just chucks it out if I'm not mistaken.
If it helps, you could define a new class called NamedParameter with attributes Name and Param. You then pass this object around as parameters.

How to reuse LINQ Select Expression with arguments

I write a LINQ query and for Select clause I created an Expression to reuse it.
My query looks like this
DataContext.Single.Select(SearchSelector).ToList();
Where as Search Selector defined as
private Expression<Func<Singles, SearchSingles>> SearchSelector = s =>
new SearchSingles
{
};
The above works fine, but what if I want to use two input parameters? How would I invoke it?
private Expression<Func<Singles,string, SearchSingles>> SearchSelector = (s,y) =>
new SearchSingles
{
};
Rather than having a field that stores the expression, have a method that creates the expression that you need given a particular string:
private static Expression<Func<Singles, SearchSingles>> CreateSearchSelector(
string foo)
{
return s =>
new SearchSingles
{
Foo = foo,
};
}
You can then use this method like so:
DataContext.Single.Select(CreateSearchSelector("Foo")).ToList();
what about leaving the signature alone and passing additional parameters as captured values? It might have limited use as an initialized member variable, like this, but if you assign from within some worker function, rather than initialize it during class construction you'd have more power.
private Func<Singles, SearchSingles> SearchSelector = s =>
new SearchSingles
{
someVal = capturedVariable,
someOther = s.nonCapturedVar
};
that would work if capturedVariable were a static member
or
private Func<Singles, SearchSingles> SearchSelector = null;
private void WorkerFunction(string capturedVariable, bool capAgain, bool yetAgain)
{
SearchSelector = s => {
bool sample = capAgain;
if (capturedTestVar)
sample = yetAgain;
return new SearchSingles
{
someVal = capturedVariable,
someOther = s.nonCapturedVar,
availability = sample
};
};
};
you could have all sorts of fun
*EDIT* references to Expression removed and clarifications

Searching Generic Class Field Names

I have a method which returns a generic list of something.
I want to be able to pass this method a string value which will represent one of the fields in the class's name, and based on this I want to order the data by this field. I want to do this in a different way other than a switch.
For example;
private void GetList()
{
var list = GetResearchStocks("Sedol");
}
private List<Stocks> GetResearchStocks(string orderBy = "")
{
var currentResearchStockList = _reports.GetZeusData("tblResearchStocks");
var researchStocklist = currentResearchStockList.AsEnumerable().ToList();
_zeusResearchStocks = researchStocklist.Select(item => new ZEUS_ResearchStocks
{
Sedol = item[0].ToString(),
StockName = item[1].ToString(),
}
).ToList();
if (orderBy != "")
{
return _zeusResearchStocks.OrderBy(o=>o.) ?????? < What to do here?
}
return _zeusResearchStocks;
}
You may either use Dynamic Linq library (DLinq) or you may just write an extension method using reflection to use string variables in order statements.
For the second option, refer to this example.

Categories

Resources