I have a piece of code like this.
I write this because I love extension methods and lambda expression:
public static class TuneingRules
{
public static Func<HtmlNode, bool> IsNodeHavingClearNone = (node) =>
{
if (node.HasAttributes)
{
// HtmlAttribute atr = item.Attributes.Where(at => at.Name == "id" && at.Value == "hello").FirstOrDefault();
HtmlAttribute atr = node.Attributes.Where(at => at.Name == "style").FirstOrDefault();
if (atr != null)
{
return Regex.Match(atr.Value, "clear\\s*:\\s*none;").Success;
}
}
return true;
};
}
and extension method like this.
public static class ExtensionMethods
{
#region Ignoring Rules
public static bool Ignore(this HtmlNode Node, Func<HtmlNode,bool> func) {
return func(Node);
}
#endregion
}
now I have two approaches to use this piece of code..
1 case
if (!htmlNode.Ignore(TuneingRules.IsNodeHavingClearNone)){
//then do somethings
}
// here i am open to write lambda expression like this.
if (!htmlNode.Ignore( node => node.innerText =="" ){
//then do somethings
}
2 case
if (!TuneingRules.IsNodeHavingClearNone(htmlNode)) {
//then do something
}
I'm afraid that there are any performance issues if TuneingRules
has many static Func<HtmlNode,bool> objects. Do i need to refactor my code?
In the first case there is an extra call going through ignore function...
but in the second case i can call the function object directly.
Or is there another way to write this code in order to stick with lambda as well as extension methods?
No, there is no performance issue.
There will be a small performance hit the first time that you use the TuneingRules class, as the static constructor will be called and initialise all the static variables. That should however be quite small compared to the actual work that the function does.
Likewise, doing one extra method call is negligible compared to the work that the function does. It's even possible that the extension method call will be inlined by the JIT compiler, so that the executed code will actually do the same thing as in your second case.
Related
So I'm trying to make a 2D game (C#) where the player has different skills that they can use. The problem is that I don't know how to call a function with the string containing the skill name. There is always another way to do it, which is by making a really long list full of if-statements to check if the skill is named something, but this seems far from ideal.
Let's say a skill is called "Skill1". Is there any way to call a function called Skill1() by using the string "Skill1"? It would really help with making the code look good.
Thanks in advance
What you're looking for are delegates (and more specifically a dictionary of delegates).
void Main()
{
var things = new Dictionary<string, Action>
{
{"Thing1", DoThing1},
{"Thing2", DoThing2},
{"Thing3", DoThing3},
};
things["Thing1"]();
things["Thing3"]();
things["Thing2"]();
}
public void DoThing1()
{
Console.WriteLine("In Do Thing 1");
}
public void DoThing2()
{
Console.WriteLine("In Do Thing 2");
}
public void DoThing3()
{
Console.WriteLine("In Do Thing 3");
}
For more information, search for Delegates, Actions and Funcs.
Delegates are a good option but if you want to keep it simple you can use switch statement instead of if statements and it will be easy to maintain.
It's basic but maybe it will help
static void Main(string[] args)
{
Console.WriteLine("call skill");
string _skill = Console.ReadLine();
CallSkills(_skill);
}
public static void CallSkills(string skillname)
{
switch (skillname)
{
case "skill1":
//call skill1 method
break;
case "skill2":
//call skill2 method
break;
case "skill3":
//call skill3 method
break;
case "skill4":
//call skill4 method
break;
case "skill5":
//call skill5 method
break;
default:
break;
}
}
An alternative to using a dictionary with delegates is to using a switch expression with delegates.
One possible approach is to create a method that associates all relevant skill names with the appropriate Skill* method, as well as using the discard pattern (_ => ...; here: _ => null) to define a default value for any skillName that does not match any defined skill names in the expression:
private static Action GetSkillAction(string skillName)
{
return skillName switch
{
"Skill1" => Skill1,
"Skill2" => Skill2,
_ => null
};
}
To make it easier to use that method, you could create a method to actually perform a skill (by skill name). This method handles receiving a non-existing skill by only calling the associated action if the action is unlike null:
public static void PerformSkillAction(string skillName)
{
var action = GetSkillAction(skillName);
if (action != null)
{
action();
}
}
Now, calling
PerformSkillAction("Skill1");
will result in a call to Skill1(), whereas calling
PerformSkillAction("Banana");
will not call anything.
Example fiddle here.
I try to get my head around the Task/Func/Action/await functionality of C# but still need your help:
I have a button click event handler in my gui thread that, when called, does the following:
Func<int> t = new Func<int>(CountToBillion);
int result = await Task.Run(t);
//do something with result value...
The method itself is declared as:
private int CountToBillion()
{
//count to 1 billion and return 0
}
So far, this runs without error. But if I want to pass a parameter to CountToBillion() everything I try goes horribly wrong.
Func<int, int> t = new Func<int, int>(CountToBillion);
int result = Task.Run(t???);
// ...
private int CountToBillion(int workerId)
{
//count to 1 billion and return 0
}
For now, I would like to NOT use lambda expressions, because I do not understand them yet. I always see this solution:
await Task.Run(() => methodcall(...));
But there must be away to use this without lambda expressions, or am I completely off track here? How would I use Task.Run() with plain old simple objects?
The Task.Run method doesn't have an overload that allows you to take a Func<T, R>.
You can use a closure, but that's something you say you don't want to use, just for practice sake:
var someInput = 42;
// And there are side-effects to calling the Result property getter
// but that's a totally different issue I am ignoring for now
// because it depends on the application context
var result = Task.Run(() => CountToBillion(someInput)).Result;
So then, re-structure your code. Do what the C# compiler does to closures. Do that transformation yourself manually.
So instead of writing your CountToBillion method like so:
public static void Main(string[] args)
{
}
static int CountToBillion(int someInput) { ... }
Do this:
public static void Main(string[] args)
{
var foo = new Foo(42);
var result = Task.Run(foo.CountToBillion).Result;
}
class Foo
{
public Foo(int someInput) { SomeInput = someInput; }
public int SomeInput { get; set; }
public int CountToBillion() { ... }
}
I am skeptical of your desire to avoid the use of anonymous methods or lambda expressions. They are convenient, idiomatic, and functionally you're going to wind up doing something that is essentially the same anyway, but without the compiler's help.
You can read the Task.Run() docs as well as anyone else, I presume, so you can easily see that there's not any overload for that method that provides for a parameterized invocation of the task delegate. So you will need to provide that for yourself.
You can do it exactly the same way that the C# compiler would do it for you, if you'd be willing to use a lambda expression. In particular, you would need to declare a type to hold the parameter, and which has a suitable method to use for the task invocation.
For example:
class CountToBillionWrapper
{
private readonly int _workerId;
public CountToBillionWrapper(int workerId)
{
_workerId = workerId;
}
public int CountToBillion()
{
// do whatever, using the _workerId field as if it had been passed to the method
}
}
Then you can do this:
CountToBillionWrapper wrapper = new CountToBillionWrapper(workerId);
int result = await Task.Run(wrapper.CountToBillion);
Since this is, essentially, how the C# compiler implements a closure that would be needed when using a lambda expression that captures the variables that you want to pass to the method, I don't really see the point in doing it this way. Seems like extra work for harder-to-read code to me.
But maybe you prefer the explicitness. If so, the above will work to do what you're asking.
I got this class
public class fooBase
{
public List<MethodsWithCustAttribute> MethodsList;
public bool fooMethod([CallerMemberName]string membername =""))
{
//This returns a value depending of type and method
}
public void GetMethods()
{
// Here populate MethodsList using reflection
}
}
And This Attribue Class
// This attribute get from a database some things, then fooMethod check this attribute members
public class CustomAttribute
{
public string fullMethodPath;
public bool someThing ;
public bool CustomAttribute([CallerMemberName]string membername ="")
{
fullMethodPath = **DerivedType** + membername
// I need here to get the type of membername parent.
// Here I want to get CustClass, not fooBase
}
}
Then I have this
public class CustClass : fooBase
{
[CustomAttribute()]
public string method1()
{
if (fooMethod())
{
....
}
}
}
I need the Type name of the CallerMember, there is something like [CallerMemberName] to get the Type of class owner of the Caller ?
It isn't foolproof, but the convention with .NET is to have one type per file and to name the file the same as the type. Our tooling also tends to enforces this convention i.e. Resharper & Visual Studio.
Therefore it should be reasonable to infer the type name from the file path.
public class MyClass
{
public void MyMethod([CallerFilePath]string callerFilePath = null, [CallerMemberName]string callerMemberName = null)
{
var callerTypeName = Path.GetFileNameWithoutExtension(callerFilePath);
Console.WriteLine(callerTypeName);
Console.WriteLine(callerMemberName);
}
}
Caller member
Granted, getting the caller member name is not "natural" in the object model.
That's why the C# engineers introduced CallerMemberName in the compiler.
The real enemy is duplication, and stack-based workarounds are inefficient.
[CallerMemberName] allows to get the information without duplication and without ill-effect.
Caller type
But getting the caller member type is natural and easy to get without duplication.
How to do it
Add a "caller" parameter to fooMethod, no special attribute needed.
public bool fooMethod(object caller, [CallerMemberName]string membername = "")
{
Type callerType = caller.GetType();
//This returns a value depending of type and method
return true;
}
And call it like this:
fooMethod(this);
This answer the question
You stated
// Here I want to get CustClass, not fooBase
and that's exactly what you'll get.
Other situations where it would not work, with solutions.
While this exactly answers your requirements, there are other, different, cases where it wouldn't work.
Case 1: When caller is a static methods (there is no "this").
Case 2: When one wants the type of the caller method itself, and not the type of the caller itself (which may be a subclass of the first).
In those cases, a [CallerMemberType] might make sense, but there are simpler solutions.
Notice that the static caller case is simpler: there is no object so no discrepancy between it and the type of the calling method. No fooBase, only CustClass.
Case 1: When caller is a static methods (there is no "this")
If at least one caller is a static method, then don't do the GetType() inside the method but on call site, so don't pass "this" to the method but the type:
public bool fooMethodForStaticCaller(Type callerType, [CallerMemberName]string membername = "")
Static caller will do:
public class MyClassWithAStaticMethod // can be CustClass, too
{
public static string method1static()
{
fooMethodForStaticCaller(typeof(MyClassWithAStaticMethod));
}
}
To keep compatibility with object callers, either keep the other fooMethod that takes the this pointer, or you can remove it and object callers will do:
fooMethod(this.GetType());
You can notice that the typeof(MyClassWithAStaticMethod) above repeats the class name and it's true. It would be nicer to not repeat the class name, but it's not such a big deal because this repeats only once, as a typed item (not a string) and inside the same class. It's not as serious a problem as the original problem that the [CallerMemberName] solves, which was a problem of repeating the caller name in all call sites.
Case 2: When one wants the type of the caller method, not the type of the caller
For example, in class fooBase you want to call anotherFooMethod from object context but want the type being passed to always be fooBase, not the actual type of the object (e.g. CustClass).
In this case there is a this pointer but you don't want to use it. So, just use actually the same solution:
public class fooBase
{
[CustomAttribute()]
public string method1()
{
if (anotherFooMethod(typeof(fooBase)))
{
....
}
}
}
Just like in case 1, there is one repetition, not one per call site, unless you have an pre-existing problem of rampant code duplication, in which case the problem being addressed here is not the one you should worry about.
Conclusion
[CallerMemberType] might still make sense to avoid duplication at all, but:
anything added to the compiler is a complexity burden with maintenance cost
given the existing solutions I'm not surprised there are items with higher priority in the C# development team list.
See Edit 2 for the better solution.
The information that CompilerServices provides is too little in my opinion to get the type from the calling method.
What you could do is use StackTrace (see) to find the calling method (using GetMethod()) and get the type using Reflection from there.
Consider the following:
using System.Runtime.CompilerServices;
public class Foo {
public void Main() {
what();
}
public void what() {
Bar.GetCallersType();
}
public static class Bar {
[MethodImpl(MethodImplOptions.NoInlining)] //This will prevent inlining by the complier.
public static void GetCallersType() {
StackTrace stackTrace = new StackTrace(1, false); //Captures 1 frame, false for not collecting information about the file
var type = stackTrace.GetFrame(1).GetMethod().DeclaringType;
//this will provide you typeof(Foo);
}
}
}
Notice - As #Jay said in the comments, it might be pretty expensive but it does the work well.
Edit:
I found couple of arcticles comparing the performance, and it is indeed horrbily expensive comparing to Reflection which is also considered not the best. See: [1] [2]
Edit 2:
So after a look in depth on StackTrace, it is indeed not safe to use it and even expensive.
Since every method that will be called is going to be marked with a [CustomAttribute()], it is possible to collect all methods that contains it in a static list.
public class CustomAttribute : Attribute {
public static List<MethodInfo> MethodsList = new List<MethodInfo>();
static CustomAttribute() {
var methods = Assembly.GetExecutingAssembly() //Use .GetCallingAssembly() if this method is in a library, or even both
.GetTypes()
.SelectMany(t => t.GetMethods())
.Where(m => m.GetCustomAttributes(typeof(CustomAttribute), false).Length > 0)
.ToList();
MethodsList = methods;
}
public string fullMethodPath;
public bool someThing;
public CustomAttribute([CallerMemberName] string membername = "") {
var method = MethodsList.FirstOrDefault(m=>m.Name == membername);
if (method == null || method.DeclaringType == null) return; //Not suppose to happen, but safety comes first
fullMethodPath = method.DeclaringType.Name + membername; //Work it around any way you want it
// I need here to get the type of membername parent.
// Here I want to get CustClass, not fooBase
}
}
Play around with this approach to fit your precise need.
Why not just use public void MyMethod<T>(params) { string myName = typeof(T).Name }
then call it Logger.MyMethod<Form1>(...);
You avoid the performance hit of reflection, if you just need basic info.
I want to disallow calls to a specific method (MessageBox.Show) via a custom FxCop rule. I know the mechanics of how to get an FxCop rule custom-implemented (the XML file, inheriting from BaseIntrospectionRule, etc.) My question here is what I put in the "Check" method.
Below is the initial draft I have based on poking around a lot on the web, but I'm very puzzled as to what I would actually populate in the two fields marked with ????? below.
I'm not sure even this solution, as it exists, would work. What is the fool-proof to make sure I'm doing what I want -- which is catching all calls to MessageBox.Show?
public override ProblemCollection Check(Member member)
{
Method method = member as Method;
if (method == null)
{
return null;
}
MetadataCollection<Instruction>.Enumerator enumerator = method.Instructions.GetEnumerator();
while (enumerator.MoveNext())
{
Instruction current = enumerator.Current;
switch (current.OpCode)
{
case OpCode.Call:
case OpCode.Callvirt:
{
Method method3 = current.Value as Method;
if (method3 == **?????**)
{
Problem item = new Problem(base.GetResolution(**?????**), current);
base.Problems.Add(item);
}
break;
}
}
}
return base.Problems;
}
You might want to take a look at how the built-in SpecifyMessageBoxOptions rule is built using a decompiler like Reflector. There are other possible approaches, but name comparison is usually fine unless you have reason to believe that it will cause excessive false positives.
How about something like this?
public override ProblemCollection Check(Member member)
{
Method method = member as Method;
if (method != null)
{
this.Visit(method.Body);
}
return this.Problems;
}
public override void VisitMethodCall(MethodCall call)
{
base.VisitMethodCall(call);
Method targetMethod = (Method)((MemberBinding)call.Callee).BoundMember;
if (targetMethod.Name.Name.Contains("MessageBox.Show"))
this.Problems.Add(new Problem(this.GetResolution(), call));
}
I have a class that creates a List<Action<int>> and holds on to them until a later time. This class can add and remove delegates from this list. This works well as long as people don't get too fancy. To combat anonymous function (which can't be removed) I check against the target of the delegate being null. If its null I throw an exception. The problem comes in when there is an anonymous delegate that contains a function. This has a target, but is just as unremovable. The simplified code below illustrates my issues
public class MyDelegateContainer
{
List<Action<int>> m_Container = new List<Action<int>>();
public void Add(Action<int> del)
{
if (del.Target == null)
{
throw new Exception("No static handlers");
}
m_Container.Add(del);
}
public bool Remove(Action<int> del)
{
if (m_Container.Contains(del))
{
m_Container.Remove(del);
return true;
}
return false;
}
}
public class MyFakeActionClass
{
public void Test(int temp) { }
}
class Program
{
static void Main(string[] args)
{
bool removed = false;
int counter = 0;
MyDelegateContainer container = new MyDelegateContainer();
MyFakeActionClass fake = new MyFakeActionClass();
//container.Add(p => { }); //Throws, this is what I want to happen
container.Add(fake.Test); //Works, this is the use case
removed = container.Remove(fake.Test); //Works, this is the use case
Debug.Assert(removed);
container.Add(p => { fake.Test(p); counter++; }); //Works but I would like it not to
removed = container.Remove(p => { fake.Test(p); counter++; }); //doesn't work
Debug.Assert(removed);
}
}
I need some way to identify
p => { fake.Test(p); counter++; }
is an anonymous function so I can throw if someone tries it. Thanks for any help
EDIT: I should note that I could use an Action<int> variable for the anonymous function and everything would work, but the Add and Remove are never in the same scope in practice.
In your example, the caller is responsible from removing the handler. So, if the caller doesn't want to remove the handler, it won't get removed, no matter if the handler is an anonymous delegate/lambda or not.
My suggestion is to change the delegate container to something like this:
public class MyDelegateContainer
{
List<Action<int>> m_Container = new List<Action<int>>();
public Action Add(Action<int> del)
{
m_Container.Add(del);
return new Action(() =>
{
m_Container.Remove(del);
});
}
}
The caller is still responsible for removing the handler, but instead of passing the handler again to the container, it receives a "token" that it can save and use later to remove the handler.
There is no way to reliably determine whether a function is "anonymous" because all functions have names to the CLR. It's only anonymous within the language that generates it, and that's compiler-dependent. You may be able to determine the algorithm used by Microsoft's current C# compiler, only to have it stop working on C# 5 or Mono.
Since you want to prevent users of your type from writing code that uses it wrong, you just need to throw an exception at some point that will make their program crash. What I would do is throw the exception in the Remove function when the target delegate isn't found. At that point your users will still get a crash and the only way to fix it is to write the delegate in some way that it's removable.
As an added bonus, you will catch bugs where somebody tries to remove delegates twice or that were never added in the first place. The code would look like this:
public bool Remove(Action<int> del)
{
if (m_Container.Contains(del))
{
m_Container.Remove(del);
return true;
}
throw new ArgumentException("Attempt to remove nonexistent delegate");
}
I would use introspection to check the names of the methods.
Anonymous methods typically have very predictable names. (I don't remember the exact format, but run some tests, and it should be obvious).
The drawback would be that if anyone created a non-anonymous method, but decided to name it anonMethod123 (or whatever the format is...) It would be falsely rejected.
Of course you can remove an anonymous method, you just need to have a reference to the same anonymous method.
var myAnonymousMethod = p => { fake.Test(p); counter++; };
container.Add(myAnonymousMethod);
removed = container.Remove(myAnonymousMethod);
As jonnii suggested in a comment, another way you could implement it is with a dictionary:
public class MyDelegateContainer
{
Dictionary<string, Action<int>> m_Container =
new Dictionary<string, Action<int>>();
public void Add(string key, Action<int> del)
{
m_Container.Add(key, del);
}
public bool Remove(string key)
{
return m_Container.Remove(key);
}
}
Then you could easily remove a known delegate at some arbitrary point in your code just by knowing what name was used to add it:
container.Add("fake.Test", fake.Test);
removed = container.Remove("fake.Test");
Debug.Assert(removed);
container.Add("anon", p => { fake.Test(p); counter++; });
removed = container.Remove("anon"); // works!
Debug.Assert(removed);
Old question I know but I would think that this would be a current (and future) proofed way of checking if a method is anonymous:
bool isAnonymous = !System.CodeDom.Compiler.CodeGenerator.IsValidLanguageIndependentIdentifier(del.Method.Name);
The runtime name of the anonymous method would have to be invalid if used at compilation time to ensure that it didn't clash.