Would some kind person help me sort out the output of .Net Reflector v6.5 that does not compile? I think that the symbols are out of whack but global search and replace might fix that. I don't get the odd class definition. Ideas?
[CompilerGenerated]
private sealed class <ApplicationTaskIterator>d__0 : IEnumerable<ApplicationTask>, IEnumerable, IEnumerator<ApplicationTask>, IEnumerator, IDisposable
{
private int <>1__state;
private ApplicationTask <>2__current;
public SessionMetrics <>3__sm;
public Dictionary<int, ThreadMetrics> <>7__wrap3;
public Dictionary<int, ThreadMetrics>.ValueCollection.Enumerator <>7__wrap4;
public ApplicationTask <currentTask>5__1;
public ThreadMetrics <tm>5__2;
public SessionMetrics sm;
[DebuggerHidden]
public <ApplicationTaskIterator>d__0(int <>1__state)
{
this.<>1__state = <>1__state;
}
private bool MoveNext()
{
try
{
switch (this.<>1__state)
{
case 0:
this.<>1__state = -1;
Monitor.Enter(this.<>7__wrap3 = ThreadMetrics._allThreadMetrics);
this.<>1__state = 1;
this.<>7__wrap4 = ThreadMetrics._allThreadMetrics.Values.GetEnumerator();
this.<>1__state = 2;
while (this.<>7__wrap4.MoveNext())
{
this.<tm>5__2 = this.<>7__wrap4.Current;
if ((((this.<tm>5__2._managedThread.ThreadState == System.Threading.ThreadState.Stopped) || object.ReferenceEquals(this.<tm>5__2._managedThread, Thread.CurrentThread)) || ((this.<currentTask>5__1 = this.<tm>5__2.CurrentApplicationTask) == null)) || ((this.sm != null) && !this.<currentTask>5__1.CurrentSessionMetrics.SessionGUID.Equals(this.sm.SessionGUID)))
{
continue;
}
this.<currentTask>5__1.Active = !this.<tm>5__2.Suspended;
this.<>2__current = this.<currentTask>5__1;
this.<>1__state = 3;
return true;
Label_010C:
this.<>1__state = 2;
}
this.<>1__state = 1;
this.<>7__wrap4.Dispose();
this.<>1__state = -1;
Monitor.Exit(this.<>7__wrap3);
break;
case 3:
goto Label_010C;
}
return false;
}
fault
{
((IDisposable) this).Dispose();
}
}
}
Used like this:
internal static IEnumerable<ApplicationTask> ApplicationTaskIterator(SessionMetrics sm)
{
return new <ApplicationTaskIterator>d__0(-2) { <>3__sm = sm };
}
That's simply what the C# compiler transforms a method containing yield return statements to.
If you want to make the code compile, you can either try to decipher what the method is doing and recreate the original version with yield return statements; or you can rename the class and all members to valid C# names.
The original method probably looked like this:
internal static IEnumerable<ApplicationTask> ApplicationTaskIterator(SessionMetrics sm)
{
lock (ThreadMetrics._allThreadMetrics)
{
foreach (var tm in ThreadMetrics._allThreadMetrics.Values)
{
if (tm._managedThread.ThreadState != ThreadState.Stopped)
{
if (!object.ReferenceEquals(tm._managedThread, Thread.CurrentThread))
{
ApplicationTask currentTask;
if ((currentTask = tm.CurrentApplicationTask) != null)
{
if (sm == null || !currentTask.CurrentSessionMetrics.SessionGUID.Equals(sm.SessionGUID))
{
currentTask.Active = !tm.Suspended;
yield return currentTask;
}
}
}
}
}
}
}
Related
I need to output tree. But this output is incorrect.
My tree is:
`
public class ElTree
{
public int L;
public string inf;
public bool PR;
public ElTree(string inf)
{
this.inf = inf;
this.PR = false;
this.L = -1;
}
}
`
Class Tree is (Here other methods that I do with Tree, the method that output Tree in in the end. I`ve also tried to do output with recursion and it work correctly, so method Add() works correctly. But I have a task to do output in iterative way). For example, when I add tree lake "k"-root, "r"-right elem, "l"-left elem then my recursive method output "lkr" but iterative method output just "ll":
`
public class Tree
{
public ElTree[] T;
public int Coun { get { return _count; } }
private int _count;
public Tree(string inf)
{
ElTree temp = new ElTree(inf);
T = new ElTree[1];
T[T.Length-1] = temp;
}
public int Find(int V, string inf)
{
if (V == T.Length) return -1;
if (V != -1)
{
if (T[V].inf == inf) return V;
int temp = Find(T[V].L, inf);
if (temp != -1)
return temp;
return temp = Find(V + 1, inf);
}
return -1;
}
public bool Empty()
{
if (Coun == 0)
{
return true;
}
else
return false;
}
public bool Add(int i, string inf, char s)
{
ElTree temp = new ElTree(inf);
switch (s)
{
case 'L':
if (T[i].L == -1)
{
Array.Resize(ref T, T.Length + 1);
T[T.Length - 1] = temp;
T[i].L = T.Length - 1;
_count++;
return true;
}
else return false;
case 'R':
if (!T[i].PR)
{
Array.Resize(ref T, T.Length + 1);
T[T.Length - 1] = temp;
T[i].PR = true;
_count++;
return true;
}
else return false;
}
return false;
}
public void TreeInStringit(int i, ref string s)//iterative output
{
Stack<int> stack = new Stack<int>();
//int i = 0;
stack.Push(i);
do
{
while (T[i].L != -1 && i < T.Length)
{
i = T[i].L;
stack.Push(i);
}
s += T[i].inf;
while (T[i].PR && i < T.Length)
{
i++;
stack.Push(i);
}
if (stack.Count != 0) stack.Pop();
} while (stack.Count != 0);
}
public void String(int V, ref string s)//recursive output
{
ElTree temp = T[V];
if (temp.L != -1)
String(temp.L, ref s);
s += temp.inf;
if (temp.PR)
String(V+1, ref s);
}
`
When I add tree like root with two elements (one on left side and one on right) it output left side of tree 2 times. But I need output all tree.
[That title may be wrong for the question, please inform me if so]
I'm coding a little maths quiz in C#, and I was wondering how to make an if statement that says something similiar to:
"if the user responds with 'this' or ' this'
{
do blahblahblah
}
But I don't know how to say the OR bit in C#, I looked through the C# operators page, but kind of got lost in the technical jargon (I'm a rookie).
This is what I have so far:
Console.WriteLine("What is 200 / 5?");
string sFirstAnswer = Console.ReadLine();
if (sFirstAnswer == "40" || " 40")
{
sUser1Score++;
Console.WriteLine("\n Correct, 200 / 5 = 40. You have been awarded 1 point.");
Console.ReadLine();
}
Write
if (sFirstAnswer == "40" || sFirstAnswer == " 40")
or better yet, trim the answer:
if (sFirstAnswer.Trim() == "40")
if (sFirstAnswer == "40" || sFirstAnswer == "40")
You can create a list of allowed answers and then check it's in the list.
var correctFirstAnswers = new List<string>{"40", " 40"};
if (correctFirstAnswers.Contains(sFirstAnswer))
this is more readable than || when there are multiple possible answers.
I thought I might give an (over-the-top) example of what I meant to make it a bit more Dynamic
A few classes now help to ask you the questions, and with a few functions built around it, you can easily show your questions in a menu format, and then ask the question, with random nr's (only whole number division was a bit more annoying :))
You could make it easier that the Generate method limits the range a bit more, but I just thought I wanted to give you an idea of how it could look like
using System;
using System.Collections.Generic;
namespace MathQuiz
{
class Program
{
interface IExercise
{
string Title { get; }
void Generate();
}
abstract class Exercise<TResult> : IExercise
{
public virtual string Title
{
get
{
return "Exercise";
}
}
public abstract bool isCorrect(TResult reply);
public abstract TResult Solve();
public abstract bool TryParse(string value, out TResult result);
public abstract void Generate();
}
abstract class ExerciseWith2Items<TSource, TResult> : Exercise<TResult>
{
public virtual TSource Item1 { get; set; }
public virtual TSource Item2 { get; set; }
public abstract string Operator { get; }
public override string ToString()
{
return string.Format("{0} {1} {2}", Item1, Operator, Item2);
}
}
abstract class WholeNumberExercise : ExerciseWith2Items<int, int>
{
public override void Generate()
{
Random next = new Random();
Item1 = next.Next(100) + 15;
Item2 = next.Next(100) + 15;
}
public override bool TryParse(string value, out int result)
{
return int.TryParse(value, out result);
}
}
class Division : WholeNumberExercise
{
protected bool IsPrime(int nr)
{
int max = (int)Math.Sqrt(nr);
if (nr <= 2)
{
return true;
}
for (int i = 2; i < max; i++)
{
if (nr % i == 0)
{
return false;
}
}
return true;
}
public override int Item1
{
get
{
return base.Item1;
}
set
{
// primes cannot be divived, so increase the value until we don't have a prime
while (IsPrime(value))
{
value++;
}
base.Item1 = value;
}
}
public override int Item2
{
get
{
return base.Item2;
}
set
{
if (value <= 0)
{
// minimum 2
value = 2;
}
// small override: we only want whole number division, so change the nr to the closest nr that has no rest after division
int closest = 0;
while ((value - closest > 1 && Item1 % (value - closest) != 0) ||
(value + closest < Item1 && Item1 % (value + closest) != 0))
{
closest++;
}
// in case closest == 0, it doesn't really change anything
if (Item1 % (value - closest) == 0)
{
value -= closest;
}
else
{
value += closest;
}
base.Item2 = value;
}
}
public override string Operator
{
get { return "/"; }
}
public override bool isCorrect(int reply)
{
return reply == (Item1 / Item2);
}
public override void Generate()
{
Random r = new Random();
Item1 = r.Next(500) + 100;
Item2 = r.Next(50) + 2;
}
public override int Solve()
{
return (Item1 / Item2);
}
}
class Multiplication : WholeNumberExercise
{
public override string Operator
{
get { return "*"; }
}
public override bool isCorrect(int reply)
{
return reply == (Item1 * Item2);
}
public override int Solve()
{
return (Item1 * Item2);
}
}
class Addition : WholeNumberExercise
{
public override string Operator
{
get { return "+"; }
}
public override bool isCorrect(int reply)
{
return reply == (Item1 + Item2);
}
public override int Solve()
{
return (Item1 + Item2);
}
}
class Subtraction : WholeNumberExercise
{
public override string Operator
{
get { return "-"; }
}
public override bool isCorrect(int reply)
{
return reply == (Item1 - Item2);
}
public override int Solve()
{
return (Item1 - Item2);
}
}
static IExercise ShowMenu(IList<IExercise> exercises)
{
int menu;
do
{
Console.Clear();
Console.WriteLine("Test your match skills :)\r\n");
for (int i = 0; i < exercises.Count; i++)
{
Console.WriteLine("\t{0}\t{1}", i, exercises[i].GetType().Name);
}
Console.WriteLine("\r\n\t99\tExit\r\n");
Console.Write("Please enter your choice: ");
if (!int.TryParse(Console.ReadLine(), out menu))
{
// wrong input
menu = -1;
}
if (menu != 99)
{
if (menu >= exercises.Count)
{
menu = -1;
}
}
} while (menu < 0);
IExercise result = null;
if (menu != 99)
{
result = exercises[menu];
}
return result;
}
static void Solve(IExercise exercise)
{
if (exercise == null)
{
return;
}
if (!(exercise is WholeNumberExercise))
{
Console.WriteLine("Don't know how to solve this exercise, please contact developer :)");
Console.ReadLine();
return;
}
var solvable = exercise as WholeNumberExercise;
solvable.Generate();
Console.Write("{0}: '{1}' = ", solvable.GetType().Name, exercise);
int reply;
bool validAnswerGiven;
do
{
validAnswerGiven = solvable.TryParse(Console.ReadLine(), out reply);
if (validAnswerGiven)
{
if (solvable.isCorrect(reply))
{
Console.WriteLine("Correct!");
}
else
{
Console.WriteLine("Incorrect, the correct result is {0}", solvable.Solve());
}
}
else
{
Console.WriteLine("Please enter valid value (whole number)!");
}
} while (!validAnswerGiven);
Console.ReadLine();
}
static void Main(string[] args)
{
IList<IExercise> potentialExercises = new List<IExercise>()
{
new Addition(),
new Subtraction(),
new Division(),
new Multiplication()
};
IExercise selectedExercise;
do
{
selectedExercise = ShowMenu(potentialExercises);
Solve(selectedExercise);
} while (selectedExercise != null);
Console.WriteLine("Program completed!");
}
}
}
it is runnable code, so copy and paste in visual studio console project should do the trick ;)
In addition to the above you could also try to convert the string to an integer
int number = 0
bool result = Int32.TryParse(Console.ReadLine(), out number);
if (number== 40){
...
}
number will be 0 if conversion fails to int and result false but for your case you dont care its not 40...
MSDN Int TryParse
Since you're validating an answer from an equation, you want to Parse it and get it into a numeric form pronto.
var answer = Convert.ToInt32(sFirstAnswer.Trim());
var expected = 40;
if(answer == expected){
//gold ribbon
}
I have a simple invoker where, in order to be able to use a cache library , I need to know the name of the invoked method of an object that is a parameter of a Func delegate.
class Program
{
static void Main(string[] args)
{
var proxy = new Proxy();
Invoker.invoke(proxy, p => p.formatSomething("Dumb test"));
}
}
public class Proxy
{
public string formatSomething(string input){
return String.Format("-===={0}====-", input);
}
}
public static class Invoker
{
public static void invoke(Proxy proxy, Func<Proxy,string> online){
//Some caching logic that require the name of the method
//invoked on the proxy (in this specific case "formatSomething")
var methodName = ??;
if (IsCached(proxyName, methodName)){
output = GetFromCache(proxyName, methodName);
}else{
output = online(proxy);
}
}
}
These are some possible (bad) solutions:
Solution 1: Add a string parameter passing the method name (error prone)
public static class Invoker
{
public static void invoke(Proxy proxy, Func<Proxy,string> online, string methodName){
if (IsCached(proxyName, methodName)){
output = GetFromCache(proxyName, methodName);
}else{
output = online(proxy);
}
}
}
Solution 2: using Expression with possible performance issues.
public static class Invoker
{
public static void invoke(Proxy proxy, Expression<Func<Proxy,string>> online){
var methodName = ((MethodCallExpression)online.Body).Method.Name;
if (IsCached(proxyName, methodName)){
output = GetFromCache(proxyName, methodName);
}else{
output = online.Compile()(proxy);
}
}
}
Solution 3: using Expression as another parameter (error prone).
public static class Invoker
{
public static void invoke(Proxy proxy,Func<Proxy,string> online, Expression<Func<Proxy,string>> online2){
var methodName = ((MethodCallExpression)online2.Body).Method.Name;
if (IsCached(proxyName, methodName)){
output = GetFromCache(proxyName, methodName);
}else{
output = online(proxy);
}
}
}
Do you know any other better way to inspect and get the methodName the Invoker needs?
NOTE:
I'm not searching a caching mechanism for the online function result because I already have it.
The only problem is that this cache requires the proxy methodName invoked in the Func delegate.
You need an expression to parse the method's call name, but you can introduce some kind of two-level cache: one for the actual method call (which does not expire), and one for the method's call result (which may expire).
I think, your second solution goes into the right direction; just compile the expression only once.
public static class Invoker {
public static void Invoke(Proxy proxy, Expression<Func<Proxy,string>> online) {
var methodName = ((MethodCallExpression)online.Body).Method.Name;
if (IsCached(proxyName, methodName)) {
output = GetFromCache(proxyName, methodName);
} else {
if (IsFuncCached(methodName)) {
func = GetFuncFromCache(methodName);
} else {
func = online.Compile();
// add func to "func cache"...
}
output = func(proxy);
}
}
}
I tried to adapt your code as an example, I hope it makes sense.
I have recently implemented a solution for inspecting IL instructions of a CLR method.
You can use it like this:
using System;
using System.Linq;
using Reflection.IL;
namespace StackOverflow
{
class Program
{
static void Main(string[] args)
{
var proxy = new Proxy();
Invoker.invoke(proxy, p => p.formatSomething("Dumb test"));
}
}
public class Proxy
{
public string formatSomething(string input)
{
return String.Format("-===={0}====-", input);
}
}
public static class Invoker
{
public static void invoke(Proxy proxy, Func<Proxy, string> online)
{
//Some caching logic that require the name of the method
//invoked on the proxy (in this specific case "formatSomething")
var methodName = online.GetCalledMethods().First().Name;
Console.WriteLine(methodName);
}
}
}
Note that the code is not thoroughly tested nor documented, but I think it should serve your needs. Here it is:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
namespace Reflection.IL
{
public struct ILInstruction
{
public OpCode Code { get; private set; }
public object Operand { get; private set; }
internal ILInstruction(OpCode code, object operand)
: this()
{
this.Code = code;
this.Operand = operand;
}
public int Size
{
get { return this.Code.Size + GetOperandSize(this.Code.OperandType); }
}
public override string ToString()
{
return this.Operand == null ? this.Code.ToString() : string.Format(CultureInfo.InvariantCulture, "{0} {1}", this.Code, this.Operand);
}
private static int GetOperandSize(OperandType operandType)
{
switch (operandType)
{
case OperandType.InlineBrTarget:
case OperandType.InlineField:
case OperandType.InlineI:
case OperandType.InlineMethod:
case OperandType.InlineSig:
case OperandType.InlineString:
case OperandType.InlineSwitch:
case OperandType.InlineTok:
case OperandType.InlineType:
return sizeof(int);
case OperandType.InlineI8:
return sizeof(long);
case OperandType.InlineNone:
return 0;
case OperandType.InlineR:
return sizeof(double);
case OperandType.InlineVar:
return sizeof(short);
case OperandType.ShortInlineBrTarget:
case OperandType.ShortInlineI:
case OperandType.ShortInlineVar:
return sizeof(byte);
case OperandType.ShortInlineR:
return sizeof(float);
default:
throw new InvalidOperationException();
}
}
}
public sealed class MethodBodyIL : IEnumerable<ILInstruction>
{
private readonly MethodBase method;
public MethodBodyIL(MethodBase method)
{
if (method == null)
throw new ArgumentNullException("method");
this.method = method;
}
public Enumerator GetEnumerator()
{
var body = this.method.GetMethodBody();
return new Enumerator(this.method.Module, this.method.DeclaringType.GetGenericArguments(), this.method.GetGenericArguments(), body.GetILAsByteArray(), body.LocalVariables);
}
IEnumerator<ILInstruction> IEnumerable<ILInstruction>.GetEnumerator()
{
return this.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public struct Enumerator : IEnumerator<ILInstruction>
{
private static readonly IDictionary<short, OpCode> codes = typeof(OpCodes).FindMembers(MemberTypes.Field, BindingFlags.Public | BindingFlags.Static, (m, criteria) => ((FieldInfo)m).FieldType == typeof(OpCode), null).Cast<FieldInfo>().Select(f => (OpCode)f.GetValue(null)).ToDictionary(c => c.Value);
private readonly Module module;
private readonly Type[] genericTypeArguments, genericMethodArguments;
private readonly byte[] il;
private readonly IList<LocalVariableInfo> localVariables;
private int offset;
private ILInstruction current;
internal Enumerator(Module module, Type[] genericTypeArguments, Type[] genericMethodArguments, byte[] il, IList<LocalVariableInfo> localVariables)
{
this.module = module;
this.genericTypeArguments = genericTypeArguments;
this.genericMethodArguments = genericMethodArguments;
this.il = il;
this.localVariables = localVariables;
this.offset = 0;
this.current = default(ILInstruction);
}
public ILInstruction Current
{
get { return this.current; }
}
public bool MoveNext()
{
if (this.offset < this.il.Length)
{
this.current = this.ReadInstruction();
return true;
}
else
{
this.current = default(ILInstruction);
return false;
}
}
public void Reset()
{
this.offset = 0;
this.current = default(ILInstruction);
}
public void Dispose()
{
this.offset = this.il.Length;
this.current = default(ILInstruction);
}
private ILInstruction ReadInstruction()
{
var code = this.ReadCode();
return new ILInstruction(code, this.ReadOperand(code.OperandType));
}
private OpCode ReadCode()
{
var code = codes[this.ReadByte()];
if (code.OpCodeType == OpCodeType.Prefix)
code = codes[(short)(code.Value << 8 | this.ReadByte())];
return code;
}
private object ReadOperand(OperandType operandType)
{
switch (operandType)
{
case OperandType.InlineBrTarget:
case OperandType.InlineI:
case OperandType.InlineSwitch:
return this.ReadInt32();
case OperandType.InlineField:
case OperandType.InlineMethod:
case OperandType.InlineTok:
case OperandType.InlineType:
return this.ReadMember();
case OperandType.InlineI8:
return this.ReadInt64();
case OperandType.InlineNone:
return null;
case OperandType.InlineR:
return this.ReadDouble();
case OperandType.InlineSig:
return this.ReadSignature();
case OperandType.InlineString:
return this.ReadString();
case OperandType.InlineVar:
return this.ReadLocalVariable();
case OperandType.ShortInlineBrTarget:
case OperandType.ShortInlineI:
return this.ReadByte();
case OperandType.ShortInlineR:
return this.ReadSingle();
case OperandType.ShortInlineVar:
return this.ReadLocalVariableShort();
default:
throw new InvalidOperationException();
}
}
private byte ReadByte()
{
var value = this.il[this.offset];
++this.offset;
return value;
}
private short ReadInt16()
{
var value = BitConverter.ToInt16(this.il, this.offset);
this.offset += sizeof(short);
return value;
}
private int ReadInt32()
{
var value = BitConverter.ToInt32(this.il, this.offset);
this.offset += sizeof(int);
return value;
}
private long ReadInt64()
{
var value = BitConverter.ToInt64(this.il, this.offset);
this.offset += sizeof(long);
return value;
}
private float ReadSingle()
{
var value = BitConverter.ToSingle(this.il, this.offset);
this.offset += sizeof(float);
return value;
}
private double ReadDouble()
{
var value = BitConverter.ToDouble(this.il, this.offset);
this.offset += sizeof(double);
return value;
}
private MemberInfo ReadMember()
{
return this.module.ResolveMember(this.ReadInt32(), this.genericTypeArguments, this.genericMethodArguments);
}
private byte[] ReadSignature()
{
return this.module.ResolveSignature(this.ReadInt32());
}
private string ReadString()
{
return this.module.ResolveString(this.ReadInt32());
}
private LocalVariableInfo ReadLocalVariable()
{
return this.localVariables[this.ReadInt16()];
}
private LocalVariableInfo ReadLocalVariableShort()
{
return this.localVariables[this.ReadByte()];
}
object IEnumerator.Current
{
get { return this.Current; }
}
}
}
public static class ILHelper
{
public static MethodBodyIL GetIL(this MethodBase method)
{
return new MethodBodyIL(method);
}
public static IEnumerable<MethodBase> GetCalledMethods(this Delegate methodPtr)
{
if (methodPtr == null)
throw new ArgumentNullException("methodPtr");
foreach (var instruction in methodPtr.Method.GetIL())
if (IsMethodCall(instruction.Code))
yield return (MethodBase)instruction.Operand;
}
private static bool IsMethodCall(OpCode code)
{
return code == OpCodes.Call || code == OpCodes.Calli || code == OpCodes.Callvirt;
}
}
}
You can use method.Name to get the calling method name.
public static class Invoker
{
public static void invoke(Proxy proxy, Func<Proxy, string> online)
{
//Some caching logic that require the name of the method
//invoked on the proxy (in this specific case "formatSomething")
var methodName = online.Method.Name;
}
}
https://msdn.microsoft.com/en-us/library/system.multicastdelegate%28v=vs.110%29.aspx
Check the following code. If you want to get the method FULL_NAME then write the following in the first line #define FULL_NAME
public class Cache
{
private const uint DefaultCacheSize = 100;
private readonly Dictionary<string, object> _cache = new Dictionary<string, object>();
private readonly object _cacheLocker = new object();
private readonly uint _cacheSize;
public Cache(uint cacheSize = DefaultCacheSize)
{
_cacheSize = cacheSize;
}
public uint CacheSize
{
get { return _cacheSize; }
}
public TValue Resolve<TObj, TValue>(TObj item, Func<TObj, TValue> func, [CallerMemberName] string key = "")
{
#if FULL_NAME
var stackTrace = new StackTrace();
var method = stackTrace.GetFrame(1).GetMethod();
key = string.Format("{0}_{1}",
method.DeclaringType == null ? string.Empty : method.DeclaringType.FullName,
method.Name);
#endif
return CacheResolver(item, func, key);
}
private TValue CacheResolver<TObj, TValue>(TObj item, Func<TObj, TValue> func, string key)
{
object res;
if (_cache.TryGetValue(key, out res) && res is TValue)
{
return (TValue) res;
}
TValue result = func(item);
lock (_cacheLocker)
{
_cache[key] = result;
if (_cache.Keys.Count > DefaultCacheSize)
{
_cache.Remove(_cache.Keys.First());
}
}
return result;
}
}
And the usage(from a Form object):
private void CacheTest()
{
var cache = new Cache();
var text = cache.Resolve<Form, string>(this, f => f.Text);
}
I hope it helps you.
EDIT I tested using expressions without performance issues, takes about ~25ms the first time. You can adapt it to Cache class in order to extract the method call expression of the param Expression<Func<T, T1>>.
private string GetExpressionMethodCallName<T, T1>(Expression<Func<T, T1>> exp)
{
var mce = exp.Body as MethodCallExpression;
if (mce == null)
throw new InvalidOperationException("invalid expression");
return mce.Method.Name;
}
public void checkInt(Scanner MemberNrSC)
{
MemberNrSC = new Scanner(txtMemberNr.getText());
while (!MemberNrSC.hasNextInt())
{
string correctedMemberNr = Interaction.InputBox(null,"Medlemsnummer skal være et nummer, indtast det rigtige");
if (correctedMemberNr == null)
{
MemberNrCancelled = true;
break;
}
txtMemberNr.setText(correctedMemberNr);
MemberNrSC = new Scanner(txtMemberNr.getText());
MemberNrCancelled = false;
}
}
This is my java checker, for if there is only numbers in the textbox..
But as there is no scanner in C# - how would i get this method converted correct?
I have my other methods needing a scanner class - but i was hoping i could have some help in here.
BTW: i am using a visual basic inputbox - as i do not know if there is a similar way in C#.
Thanks in advance ;-)
/Rasmus
Denmark
Try this maybe
class Scanner : System.IO.StringReader
{
string currentWord;
public Scanner(string source) : base(source)
{
readNextWord();
}
private void readNextWord()
{
System.Text.StringBuilder sb = new StringBuilder();
char nextChar;
int next;
do
{
next = this.Read();
if (next < 0)
break;
nextChar = (char)next;
if (char.IsWhiteSpace(nextChar))
break;
sb.Append(nextChar);
} while (true);
while((this.Peek() >= 0) && (char.IsWhiteSpace((char)this.Peek())))
this.Read();
if (sb.Length > 0)
currentWord = sb.ToString();
else
currentWord = null;
}
public bool hasNextInt()
{
if (currentWord == null)
return false;
int dummy;
return int.TryParse(currentWord, out dummy);
}
public int nextInt()
{
try
{
return int.Parse(currentWord);
}
finally
{
readNextWord();
}
}
public bool hasNextDouble()
{
if (currentWord == null)
return false;
double dummy;
return double.TryParse(currentWord, out dummy);
}
public double nextDouble()
{
try
{
return double.Parse(currentWord);
}
finally
{
readNextWord();
}
}
public bool hasNext()
{
return currentWord != null;
}
}
source: https://stackoverflow.com/a/722524/1714342
string Str = txtMemberNr.Text.Trim();
double Num;
bool isNum = double.TryParse(Str, out Num);
if (isNum)
{
// CODE IS HERE
}
else
{
MessageBox.Show("Brugernavn skal kun indeholde tal, prøv igen!", "advarsel", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
This was the most simple way - checking whether or not there is an int/string in the textbox field.
I was hoping that you/or someone who have option for making this solved.
Thank you for your help - but i could not make it work as wanted - even though there was good use of the scanner.. thank you.
How about
public static IEnumerable<string> Scanner(this string tgt, char delim)
{
var sb = new StringBuilder();
foreach (var c in tgt)
{
if (c == delim)
{
yield return sb.ToString();
sb.Clear();
}
else sb.Append(c);
}
}
I have the following code:
class TestClass
{
public string StringValue {
get; set;
}
public int IntValue {
get; set;
}
}
class MainClass
{
private readonly List<TestClass> MyList;
public MainClass()
{
MyList = new List<TestClass>();
}
public void RemoveTestClass(string strValue)
{
int ndx = 0;
while (ndx < MyList.Count)
{
if (MyList[ndx].StringValue.Equals(strValue))
break;
ndx++;
}
MyList.RemoveAt(ndx);
}
public void RemoveTestClass(int intValue)
{
int ndx = 0;
while (ndx < MyList.Count)
{
if (MyList[ndx].IntValue == intValue)
break;
ndx++;
}
MyList.RemoveAt(ndx);
}
}
What I would like to know is if there is a simpler way, perhaps using LINQ, to replace the while loops in the 2 RemoveTestClass functions, rather then iterating through each element, like I'm doing?
You can use List<T>.FindIndex:
myList.RemoveAt(MyList.FindIndex(x => x.StringValue == strValue));
You may also want to handle the case where the element is not found:
int i = myList.FindIndex(x => x.StringValue == strValue);
if (i != -1)
{
myList.RemoveAt(i);
}
Simplest possible way I can think is finding first item, which matches the criteria and then use List.Remove to do it:
myList.Remove(myList.FirstorDefault(x=>x.StringValue == stringValue))
because Remove doesn't throw an exception when it can't find the item, above works fine. except you permited to have null values in list, which will be deleted, and I think it's not so good to have them in list.
I would do it in that way:
public void RemoveTestClass(string strValue)
{
MyList.RemoveAll(item => item.StringValue.Equals(strValue));
}
and:
public void RemoveTestClass(int intValue)
{
MyList.RemoveAll(item => item.IntValue == intValue);
}
Update:
If you only want to remove the first occurrance:
public void RemoveTestClass(int intValue)
{
var itemToRemove = MyList.FirstOrDefault(item => item.InValue == intValue);
if (itemToRemove != null)
{
MyList.Remove(itemToRemove);
}
}