Method within method or class within class

Asked

Viewed 653 times

1

Created the methods Above(), Below(), Highest(), Lowest(), Evens(), Odds(), Matching(), Repeating(), Unique()...

I need to create a structure/implement these methods inside each other, as if they were organized in directories, within a class Roll().

The goal is that those who try to use the class Roll, can bring their code as close to human language:

ApplyDamage (Physical (Roll (5,d6).Sum.OnlyEvens.Above(2)), ChosenTarget);   

Example:

using System.Linq;
using System.Collections;
using System.Collections.Generic;

public class Roll
{
    List<int>   scores;
    int         maxRange;
    public void Roll(int amountOfDices, int maxRange)
    {
        this.maxRange = maxRange;
        for (int i = 0; i < amountOfDices; i++)
        {
             scores.Add(Random.Range(1,maxRange));
        }
    }//Construtor

    public int Sum (scores)//este é o MEU Sum
    {
        public int OnlyEvens(scores){
            public int Above(scores, int threshold)
            {
                return(Evens(Above(scores)).Sum());
            }
            public int Below(scores, int threshold)
            {
                return(Evens(Below(scores)).Sum());
            }
            return(Evens(scores).Sum());
        }
        return(scores.Sum());//este Sum() é proveniente do System.Linq
    }
}
  • In what language? And this OOP is a little strange because in the examples the methods are not members of any object (ApplyDamage() instead of myInstance.ApplyDamage()). I couldn’t get it right.

  • probably meant to be chosenTarget.ApplyDamage(.....)

  • I’m sorry, I rephrased my question, and I hope it’s made clearer, thank you for your help with defining the problem.

  • What is the type of the 1st Physical() parameter? It is a list(Ienumerable)?

  • Pablo, actually "Applydamage" is a function that instantiates a "Damage" (no, Damage is not a variable in the software I’m developing) : public void Applydamage(Damage inDamageType, int inAmount, List<Gameobject> targets) {&#xA; Damage tempDamage = new Damage(inDamageType,inAmount);&#xA; foreach(var item in Listeners){&#xA; BroadcastMessage("BeforeApplyDamage",this);&#xA; }&#xA; ChosenTarget.BroadcastMessage("ApplyDamage", this);&#xA; foreach(var item in Listeners){ Broadcastmessage("Afterapplydamage", this); } }

  • Ramaral, positive, "Physical" is a Ienumerable

Show 1 more comment

1 answer

2


I will answer what it gives. The question is confusing and full of errors (nor will I comment on the use of .NET 2.0 that has not been supported for a long time). It may be that the answer is not what the AP wants, but it is what can be done with what is in the question.

To chain methods there is a technique called interface Fluent. When used in exaggeration causes more harm than good.

The secret to doing this is to always return the this (the object itself being manipulated), so the return of it is used as input to the next method.

But a lot of the code doesn’t make sense. Since the question doesn’t make it clear what needs to be done, I can’t answer this more adequately.

The builder Roll() do nothing because it already returns the object. Actually the code in the question is wrong saying it should return void, which makes me think the question is artificial and therefore difficult to answer.

The call shown from Sum() and its definition does not match. In fact the call does not make sense, has no parentheses, for example, it should be .Sum().

OnlyEvens() and the rest are methods that must be separated. Until version 6, C# does not allow methods within methods, even in version 7 its use is for something completely different. Actually it doesn’t even make sense there, putting one method inside the other doesn’t achieve the expected goal.

To do this would have to reform the whole class, I do not know if it pays. For the result to be preserved and return the this, it should be placed somewhere. But then probably the class would have a spurious datum just to meet a false requirement.

A basic idea:

public int Sum() {
    return scores.Sum();
}
public Roll OnlyEvens() {
    return Evens(scores); //imagino que este método existe em algum lugar e faça o esperado
}
public Roll Above(int threshold) {
    return Above(scores, threshold); //se isto não existir, precisa por o algoritmo aqui
}

whereas OnlyEvens() and Above() are filters, they should be applied before making the sum:

ApplyDamage(Physical(Roll(5, d6).OnlyEvens().Above(2).Sum()), ChosenTarget);

A better way to do the method, if I understand the goal:

public Roll OnlyEvens() {
    scores = scores.Where(x => x % 2);
    return this; //imagino que este método existe em algum lugar e faça o esperado
}
public Roll Above(int threshold) {
    scores = scores.Where(x =>, x > threshold);
    return this;
}

I put in the Github for future reference.

Completion

I think there’s a lot to be done before I get the result. It would probably be best to make it work perfectly the traditional way and only when this occurs ask a question to switch to a fluent interface.

  • Thank you very much, I will study this concept of Fluent interface to analyze a viable possibility within the idea you proposed... Currently Works, but ... like this : Sum(Evens(Above(Roll(5,D6),2))); E Roll "IS A CLASS" (i need Roll to be a class, because I’m intercepting the Roll constructor and making other Roll() methods modify roll behavior, such as modifying rolled data, modifying values, rerolar values, and so on) I really couldn’t write something more "cohesive" because I just didn’t start rewriting the code.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.