C# error: "Can't convert "int " into "System.Func<Creature, int>"" - c#

Please help me with this question. I'm coding come ability system in Unity3D 2019.4.1 (if you might want to know) and have had created "Roller" class for some random numbers. There is
public static Func<Creature, int> OnNumberRolled;
in "Roller" class. Some of abilities in my game must know about these random numbers and when they are rolled, they invoke some mess.
Here is an ability class:
public class ListenerEffect : Effect
{
public int OnRolledOne(Creature creature)
{
...
}
public override void CastEffect(ITargetable caster, ITargetable target)
{
Creature localCasterCreature = caster as Creature;
Roller.OnNumberRolled += OnRolledOne(localTargetCreature);
}
}
At this moment
Roller.OnNumberRolled += OnRolledOne(localTargetCreature);
error occurs. It says that it can't convert "int" into "System.Func<Creature, int>". Both classes are using System. What should I do?

Just use the name of the function. Otherwise, you are calling the function and are using the returned value.
Roller.OnNumberRolled += OnRolledOne;
If you add several handlers, keep in mind that the return values will be lost (but the last one) on invocation as OnNumberRolled().
You might have the handlers to add their results to a list or something like that, but we would need more insight on your use cases to design a satisfactory solution.
You can also iterate on handlers like this:
var handlers = OnNumberRolled.GetInvocationList();
foreach (var handler in handlers)
{
// invoke and handle each handlers'result here
Debug.Log(handler());
}

Related

Use custom attribute to skip body method

I have the following function:
public void Test(string testString)
{
//Do Stuff
}
At some points in my code, I have to repeatedly check if the parameter is empty string/null/whitespace to skip the body method. The usual ways I've done this till now, are the following:
public void Test(string testString)
{
if(!string.IsNullOrWhiteSpace(testString))
{
//Do Stuff only if string has text in it.
}
}
Or
public void Test(string testString)
{
if(string.IsNullOrWhiteSpace(testString)) { return; }
//Do Stuff only if string has text in it.
}
Is there a way to create a custom attribute that checks if the parameter of the function is empty etc, to skip the method? I've had some experiece (basic stuff), with custom attributes, but I can't figure out a way to make the attribute skip the method body.
The ideal end product of the implementation would be the following:
[SkipIfEmptyParameter]
public void Test(string testString)
{
//Do Stuff only if string has text in it.
}
Of course, any suggestion is welcome that helps minimize the recurring code if the attribute implementation is not possible.
Edit: Example of the problem I want to solve.
I have the following methods. I get from Microsoft Test Manager, some parameters that our test scenario are expecting (what the values should be). There is a SharedStep implementation that asserts the user's info:
public void AssertUser(UserDTO expectedUserInfo)
{
VerifyUserName(expectedUserInfo.name);
VerifyUserSurname(expectedUserInfo.surname);
VerifyUserAge(expectedUserInfo.age);
VerifyUserHeight(expectedUserInfo.height);
}
private void VerifyUserName(string name)
{
//If the string parameter is empty, means the MTM scenario does not
//want to validate the user's name at this point, so skip the
//verification below.
if(string.IsNullOrWhiteSpace(testString)) { return; }
//Do Stuff only if string has text in it.
}
private void VerifyUserSurname(string surname)
{
//If the string parameter is empty, means the MTM scenario does not
//want to validate the user's surname at this point, so skip the
//verification below.
if(string.IsNullOrWhiteSpace(testString)) { return; }
//Do Stuff only if string has text in it.
}
private void VerifyUserAge(string age)
{
//If the string parameter is empty, means the MTM scenario does not
//want to validate the user's age at this point, so skip the
//verification below.
if(string.IsNullOrWhiteSpace(testString)) { return; }
//Do Stuff only if string has text in it.
}
private void VerifyUserHeight(string height)
{
//If the string parameter is empty, means the MTM scenario does not
//want to validate the user's height at this point, so skip the
//verification below.
if(string.IsNullOrWhiteSpace(testString)) { return; }
//Do Stuff only if string has text in it.
}
The "Do Stuff" contain Selenium implementation that handle WebElements and might be time consuming, so if we don't want to validate that specific value, we just skip the whole method.
Now, when creating the scenarios over to Microsoft Test Manager, the shared steps allows the tester to decide what elements of the page will be validated. If some of the parameters are empty, then the code just skips the blocks and goes to w/e validation the user wants (still, the implementation is for every info the user has, but we just assign value to each parameter we want to test, and every parameter that does not have a value, just gets it's method body skipped).
The problem is, if I want to change the condition of skipping the method, I will have to go to each method and manually change the IF statement. Hence why I though it might be a good idea to have an attribute for every method that validates information.
P.S. I'm talking about hundreds of methods that have the IF implementation at the start.
The only way that I know that this can be done using attributes is aspect oriented programming using a product like post sharp and method interception. Alternatively if the methods are defined in an interface this can also be done by using RealProxy but seems more than a little overkill.
The way you are doing it is actually pretty good. But as Evk pointed out in the comments: You should extract the "skip checking" into a separate method, especially if the check is always the same and needs to be changed globally. Using an attribute would solve the problem, but is a little complicated to use.
Instead, take a look at the code below. Looks pretty clear, doesn't it? Don't use too many comments (and don't copy-paste them into every method, that is of no use). This way, you have the same benefits as if you would use a custom attribute but without the ugliness of using reflection.
public void AssertUser(UserDTO expectedUserInfo)
{
VerifyUserName(expectedUserInfo.name);
VerifyUserSurname(expectedUserInfo.surname);
VerifyUserAge(expectedUserInfo.age);
VerifyUserHeight(expectedUserInfo.height);
}
private void VerifyUserName(string name)
{
if (ShouldSkipValidation(name)) return;
// code here...
}
private void VerifyUserSurname(string surname)
{
if (ShouldSkipValidation(surname)) return;
// code here...
}
private void VerifyUserAge(string age)
{
if (ShouldSkipValidation(age)) return;
// code here...
}
private void VerifyUserHeight(string height)
{
if (ShouldSkipValidation(height)) return;
// code here...
}
// The MTM scenario does not want to validate values that satisfy the check below
private bool ShouldSkipValidation(string value)
{
return string.IsNullOrWhiteSpace(value) || value == "<>";
}
I don't think attributes make it possible to achieve what you are trying to achieve.
But you can use a custom method invoker instead:
static void Main(string[] args)
{
InvokeIfNotNullOrWhitespace((inputStr) => TestMethod(inputStr), null);
InvokeIfNotNullOrWhitespace((inputStr) => TestMethod(inputStr), "");
InvokeIfNotNullOrWhitespace((inputStr) => TestMethod(inputStr), "abc");
// RESULT:
// Trying to invoke action...
// Trying to invoke action...
// Trying to invoke action...
// I have been invoked!
}
static void InvokeIfNotNullOrWhitespace(Action<string> action, string inputString)
{
Console.WriteLine("Trying to invoke action...");
if(!string.IsNullOrWhiteSpace(inputString))
action.DynamicInvoke(inputString);
}
static void TestMethod(string input)
{
Console.WriteLine("I have been invoked!");
}
The reason why I think attributes won't work is because they can't control what is going on inside the method. Instead, "other external things" can look at those attributes and decide what to do.
To achieve what you are trying to achieve, an "external thing" would need to look at the attribute and decide if it is executed or not. This would be equivalent to what I wrote: an external invoker that unifies the "check string validity" procedure.
Here are my 4 cents on this,
Calling an attribute involves reflection, already a bad idea as
you need to find out if the attribute is set;
You're avoiding a "1 liner" in your code that actually is quite
easy to type;
Use method overloading;
You can use Aspect oriented programming that will basically inject the below samples in your code at compile time. You can control the way this works with annotations and would not have a negative effect on the generated runtime.
Here are some variations:
//1
if(string.IsNullOrEmpty(testString))
return;
//2
if(string.IsNullOrEmpty(testString) ||string.IsNullOrWhiteSpace(testString) )
return;
When going for 3 just make sure you do not mix returning null, or boolean true/false based on the "missing" text. Only you know how your code should flow.
Perhaps you are looking for method overloading
you can do that by creating 2 methods with the same name in the same class.
You can call the empty MyMethod() from the MyMethod(with string) so you do not duplicate the logic.
return string.IsNullOrEmpty(testString)?MyMethod():MyMethod(testString);

Repeatedly showing two pictures in a random order

I'm new to programming and have therefore a rather simple question.
I guess it should be possible to show two different pictures 50 times. Let’s say two different colored circles, in an random order for a second or until the user presses a certain key, but I have no idea how to start. Is there an easy way?
Maybe it's easier to start with a list of actions (either showing circle a or showing circle b) and randomly choosing one of it like the following modified code from a different question:
class Program
{
static void Main(string[] args)
{
List<Action> actions = new List<Action>();
actions.Add(() => Program.circleA());
actions.Add(() => Program.circleB());
Random random = new Random();
int selectedAction = random.Next(0, actions.Count()); // What does this line do?
actions[selectedAction].Invoke(); // And this one?
}
Afterwards I have to define what Program.circleA and Program.circleB does, right?
Should I implement this in a loop? If yes, how do I specify that each circle has to be shown 50 times before the breakout criteria is met?
I've search the Internet for similar problems, but I couldn't find a solution or maybe just couldn't understand them, so that's why I'm asking you guys and girls :)
If I understood your question correctly, your question is basically "How can I call a random action/method?" and "Is my logic of doing that okay?".
Starting with the second one (because it's easier), the answer will be the same as the answer to this simple question: "Is it doing its job?". Meaning if your logic is behaving like you wanted to, the answer is yes. If it doesn't, then no.
With the first one... It's a bit trickier because you can have many different solutions. You can use Reflection, Action, Func, custom delegates ...
(IMHO) So the "easy" way (if you have sh.. ton of methods) would be to use reflection and custom attributes, like so:
public class RandomCircleMethodAttribute : Attribute
{
public RandomCircleMethodAttribute() : base() { }
}
And then assign this Attribute to methods you want to call. Then using reflection, just get MethodInfo pointing to these methods and call them like so:
public class RandomCircleMethods
{
[RandomCircleMethod]
public void circleA() { //.. your logic here
}
[RandomCircleMethod]
public void circleB() { //.. your logic here
}
// add as many as you want
}
Then inside your EntryPoint ( Main(string[] args) ) :
List<MethodInfo> methods = typeof(RandomCircleMethods).GetMethods().Where(method => Attribute.IsDefined(method, typeof(RandomCircleMethod))).ToList();
int selectedAction = new Random().Next(0, methods.Count);
methods[selectedAction].Invoke(new RandomCircleMethods(), null);
This way you don't have to create list of Action. But this is as good as your current way of making the job done.
I would stick to your current logic though, because it's less confusing than using reflection.

Activator.CreateInstance with dynamic objects

there are many questions arround about this theme, but I didn't find one, which answers my question:
I'm toying arround with the MVVM. In order to give the views a possibility to request a ViewModel-switch, I implemented a Event in the abstract base class.
My method to switch looking like this:
private void ChangeCurrentView(Type viewType, IEnumerable<Object> constructorArguments)
{
if (_currentContent != null)
{
_currentContent.ChangeViewRequested -= view_ChangeViewRequested;
}
ViewModelBase vm;
if (constructorArguments == null)
{
vm = (ViewModelBase)Activator.CreateInstance(viewType);
}
else
{
vm = (ViewModelBase)Activator.CreateInstance(viewType, constructorArguments);
}
vm.ChangeViewRequested += view_ChangeViewRequested;
_currentContent = vm;
OnPropertyChanged("CurrentContent");
}
My problem lies in the CreateInstance: As you can see I have to check if the arguments are null and if so, I use the method without arguments. But even if the arguments are filled, for example:
public QuestionViewModel(Question question)
and the constructorArgument has just 1 object of this type, it doesn't seem to handle this proper.
is there a possibility to get this dynamic creating work, or are there other ways to make this anyhow happen?
Thanks as usual and a good start in the week.
Matthias
Edit: The error I get is "The constructor for the type "MMU.QuestionHelper.GUI.ViewModel.QuestionViewModel" was not found."
I translated it myself, because my VS is in german.

How to implement a Stack class in C#, with pre/postconditions and invariants?

Does anyone have any examples or ideas on how / what is the best way to implement a Stack class in C#? I understand that there is already a Stack class, but I need to understand how to actually implement a Stack class.
I also need advice on how to use Contracts in C# to specify preconditions, postconditions, and invariants for this class. I think I have used something similar before when creating models in the ASP.NET MVC architecture, but I'm not entirely sure if it is the same thing and works the same way. (I'm a bit lost on the preconditions/postconditions/invariants, if you couldn't already tell - so please bear with me.)
My main question - could someone give me advice on properly using Contracts for a class such as a Stack.
Yes, I have laid out effort:
public interface IStack
{
void Push(Object e);
Object Pop();
Object Top();
void EnsureCapacity();
}
}
public class Stack : IStack
{
private Object[] elements;
private int size = 0;
public Stack()
{
elements = new Object[0];
}
public void Push(Object e)
{
// check if this array capacity has been reached and increase if needed
EnsureCapacity();
elements[size++] = e;
}
public Object Pop()
{
// check if the method call is invalid for the object's current state
if (size == 0) throw new InvalidOperationException("Stack.Pop");
Object result = elements[--size];
elements[size] = null;
return result;
}
public Object Top()
{
// check if the method call is invalid for the object's current state
if (size == 0) throw new InvalidOperationException("Stack.top");
return elements[(size - 1)];
}
private void EnsureCapacity()
{
if (elements.Length == size)
{
Object[] oldElements = elements;
elements = new Object[(2 * size + 1)];
}
}
}
If you want, for getting started using Microsoft Code Contracts, I made a blog post about it once. That post covers the very basic of preconditions, post-conditions, and invariants.
As a summary of the concepts, you can think of them as follows:
Precondition is what must be true prior to a method being executed -- what clients promise your method.
Invariant is what must remain publicly true at all times as far as clients of your class are concerned.
Postcondition is what must be true following a method execution -- what your method promises to clients.
So, off the top of my head, for a stack, an easy thing to think of might be an invariant. If you're modeling the stack with an array, you might declare an invariant on the class that the array is never set to null, for example you'd define the invariant method:
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(elements != null);
}
It looks like you've already got a precondition on your pop method - you want to say that it's incumbent on the user to make sure that the stack is not empty when he executes a pop. So, at the beginning of the pop method, you'd have:
Contract.Requires(size > 0);
And finally, you might specifiy a post-condition on pop, that size will always be less than it was before the pop operation (you could get more specific if you like):
Contract.Ensures(Contract.OldValue<int>(size) > size);
Good luck with it -- contracts are cool and useful. It's a very clean way to code.
Many of collections implemented in c# are based on arrays. You could use array and add elements to the end, keep index of a top elemnet and increase it while new elements are pushed, of course array will "have to be extended" ( replaced by new one ) dynamically when new objects appear and there is no place for them in current array.
code contracts have pretty good documentation available at http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf

C# Delegates and Events logic and syntax issues

As my code suggests, I'm trying to create a delegate which will point to the StringBuff method BuffString, which creates a StringBuilder that is going to have a fair amount of settings, etc.
My problem is that, for some reason, no matter what it is I try I can't pass the reference to the StringBuff class I made within my Sprite class to the delegate's constructor without receiving an error. Ontop of that, I feel like creating an event may be useful to help initiate the delegate.
The main problem is that I'm just now barely grasping these two concepts, as well as how to use them as replacements for function pointers which are allowed in other programming languages.
If anyone has any idea on what it is I need to do to make this work, I would definitely appreciate it.
Here's the code:
public class StringBuff
{
private static StringBuilder stringBuffer = new StringBuilder();
public static StringBuilder BuffString(string _string) //--may possibly have to use IntPtr to reference stringBuffer here.
//This is the equivalent to the "strbuff_new" C++ method variant, designed to update the stringBuffer.
{
int iCounter = 0;
stringBuffer.Append(_string + " ");
iCounter += _string.Length + 1;
if (iCounter == stringBuffer.Capacity - 1)
{
stringBuffer.Capacity += stringBuffer.Capacity;
}
return stringBuffer;
}
}
public delegate void UpdateStringBuffer(StringBuff sender);
public class Sprite : SpriteInterface.ISprite
{
private StringBuff stringBuff = new StringBuff();
public event UpdateStringBuffer stringBuffEvent
{
add
{
Console.WriteLine("Adding");
stringBuffEvent += value;
}
remove
{
Console.WriteLine("Removing...");
stringBuffEvent -= value;
}
}
static void Main()
{
new Sprite().stringBuffEvent += new UpdateStringBuffer(stringBuff);
}
}
I believe you are in need for some reading. Refer to the following:
Events Tutorial
Introduction to Delegates and Events
Events and Delegates simplified
You are misunderstanding the use of events and delegate.
When you want to add an Event Handler to an event, you pass a delegate of the same type as the event (which you did correctly)
But when you create a delegate, what you should pass in the constructor (most of the time) is a Method Name and not some variable, since a delegate is a kind of pointer to a (list of) functions.
I reccomend you to read more about delegates as Akram Shahda suggested but just for now i'll tell you that the method that you should pass as parameter to the delegate constructor should have the same signature - means return the same value and accept the same parameters. so for example you could have:
// This method have the same signature as UpdateStringBufferDelegate
public void SomeMethod (StringBuff buff)
{
// Doing somthing here
}
And then you can do in your main:
// Passing method's name and not a variable!!
new Sprite().stringBuffEvent += new UpdateStringBuffer(SomeMethod);
The Actuall parameters that will be passed to the function itself (some StringBuff) only determined at the time of the invokation of the event.
You should read more about that.
Good Luck!
you are doing it wrong,
new Sprite().stringBuffEvent += new UpdateStringBuffer(stringBuff);
Above code is invalid due to following reasons.
1. stringBuff that your UpdateStringBuffer is taking is an instance of StringBuff within Sprite.
2. You are accessing stringBuff from the static Main method which does not have any idea about stringBuff where it is located.
1- The delegate's constructor can only have a parameter Method. Ex
public delegate void UpdateStringBuffer(StringBuff sender);
2- You can declare ur event and add a method to define ur method in ur Splite class. Ex:
public event UpdateStringBuffer stringBuffEvent;
public ProcessUpdateStringBuffer(UpdateStringBuffer yourMethod)
{
stringBuffEvent += yourMethod
}
3- and from ur main u can define ur method to the event and invoke it like this:
Sprite sprite = new Sprite();
sprite.ProcessUpdateStringBuffer(UpdateStringBuffer(urMethod));
sprite.stringBuffEvent(ur parameters);

Categories