0

I have a List<> full of a Class object called 'Creature', 'Creature' contains a List<> that is full of a separate Class object called 'AttackMethod'. Inside of the AttackMethod Class is a public int Method called 'RollDamage' which takes variables assigned inside of AttackMethod and calculates them to return an int.

The problem I'm having is calling that RollDamage method from my List<> of Creatures. Each Creature has a List<> of AttackMethods inside of it. What I'm trying to do is Access each Creature's AttackMethod List<> and activate the RollDamage method. The abbreviated code is as follows:

private static void MobAttacksPlayer(Objects.Creature inMob)
{    
    MobDamage = (int)inMob.creatureAttacks.RollDamage();
    Console.Write(MobDamage);
}

creatureAttacks is my public variable for the List<> inside of the Creature Class. The public was previously protected and the casting to (int) above was something else I tried, but didn't work.

public List<AttackMethod> creatureAttacks = new List<AttackMethod>();

I'm sure it's something simple that I'm overlooking; I'm fairly new to C#, but wanted to try and create and small Roguelike to learn from. As I've been writing this here, I've been going through the list of Similar questions on the right with no success. The following is my AttackMethod Class (Trimmed down to include only the Constructors and the RollDamage Method I'm trying to use)

public class AttackMethod
    {
        protected string aFlag;
        protected string eFlag;
        protected int numberDice;
        protected int numberSides;

        public AttackMethod() { }

        public AttackMethod(string inaFlag, string ineFlag, int inNumdie, 
                            int inNumSides)
        {
            aFlag = inaFlag;
            eFlag = ineFlag;
            numberDice = inNumdie;
            numberSides = inNumSides;
        }

        ~AttackMethod() { }

        public int RollDamage()
        {
            DiceBag.Dice newDie = new DiceBag.Dice();
            int ret = newDie.any(numberDice, numberSides);
            return ret;
        }
    }

DiceBag is just my die roller, and has no errors with it. Also, I don't know if it makes a difference or not, but this is a Console program, not a Windows Forms program. I'm using Visual C# Express 2010. Thank you in advance for your help.

Error 2 'System.Collections.Generic.List' does not contain a definition for 'RollDamage' and no extension method 'RollDamage' accepting a first argument of type 'System.Collections.Generic.List' could be found (are you missing a using directive or an assembly reference?) C:\Users\Carl.Prichard\Documents\Visual Studio 2010\Projects\MyRogueLike\MyRogueLike\Program.cs 1130 60 MyRogueLike

Usually when I get this error, casting it to the variable type I want resolves it

Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
  • 1
    "it didn't work" is not very helpful. Please explain the specific problem you are having. – Blorgbeard Aug 26 '14 at 01:36
  • My apologies, I thought I had explained that I wasn't able to get a result from RollDamage. The specific error it's throwing is Error 2 'System.Collections.Generic.List' does not contain a definition for 'RollDamage' and no extension method 'RollDamage' accepting a first argument of type 'System.Collections.Generic.List' could be found (are you missing a using directive or an assembly reference?) C:\Users\Carl.Prichard\Documents\Visual Studio 2010\Projects\MyRogueLike\MyRogueLike\Program.cs 1130 60 MyRogueLike – Carl Prichard Aug 26 '14 at 01:42
  • Alright, I think I understand. Posted an answer. – Blorgbeard Aug 26 '14 at 01:45

2 Answers2

2

The method RollDamage damage is a member of the AttackMethod class. inMob.creatureAttacks is a list i.e. List<AttackMethod>. This list isn't going to expose any of the methods on the AttackMethod class, it simply exposes the methods on List. You need to iterate through the list to get a reference to each of the creatures attack methods. i.e...

foreach(AttackMethod attack in inMob.creatureAttacks)
{
    var mobDamage = (int)attack.RollDamage();
    Console.Write(mobDamage);
}
Mick
  • 6,527
  • 4
  • 52
  • 67
0

What you want to do is call a method (RollDamage) on each member of a list (creatureAttacks).

You can't do that directly "on" the list. You can use foreach to iterate through the list and process each object in it, one at a time. Perhaps you want something like this:

private static void MobAttacksPlayer(Objects.Creature inMob)
{    
    var totalDamage = 0;
    foreach (var attack in inMob.creatureAttacks) 
    {
        var attackDamage = attack.RollDamage();
        Console.Write(attackDamage);
        totalDamage += attackDamage;
    }
    Console.Write(totalDamage);
}

If you just want to sum the attacks and don't care about the individual values, you could shorten the code using LINQ (be sure using System.Linq is in your usings at the top of your file):

var totalDamage = inMob.creatureAttacks.Sum(t => t.RollDamage());
Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
  • I wouldn't have mentioned Linq I think it's too advanced for someone at this level of learning. If you're going to mention it you need to mention that they must inlcude the System.Linq namespace in the using statements, and probably then explain what an extension method is etc etc etc.... It's a little too much to digest for someone at this level – Mick Aug 26 '14 at 01:49
  • Ah! So each and every List<> I have to get info from must be looped through separately? That makes sense; It's probably not important on a program this small, but I recall it being good habit to leave everything inside a Class as protected and access it via get {} and set {}. i.e. public getAtkList { get { return creatureAttacks;} } Would that produce the same result as above? – Carl Prichard Aug 26 '14 at 01:51
  • @CarlPrichard yes, that's generally a good idea, and yes, it would work the same way. – Blorgbeard Aug 26 '14 at 01:53
  • @Mick perhaps - I don't think there's harm in mentioning it though. LINQ is a very useful tool to have. – Blorgbeard Aug 26 '14 at 01:54
  • Thank you both for your help; this has fixed my problem :) – Carl Prichard Aug 26 '14 at 01:59
  • Yea it's useful, but I think it's better to understand first principles, so you can understand how LINQ works under the covers. Things like the outer variable trap http://stackoverflow.com/questions/3416758/outer-variable-trap which you can encounter with Lambda expressions and hence LINQ are difficult concepts even for a seasoned developer to understand. I would avoid exposing a novice programmer to things like that, they could easily fall into traps which might be very difficult for them to comprehend and could easily put them off programming all together. – Mick Aug 26 '14 at 03:55
  • LINQ looks deceptively simple, but it's actually a really advanced programming concept. – Mick Aug 26 '14 at 03:56
  • I'm not taking responsibility for OP's learning - I'm just providing relevant information. I trust the learner to decide if something is too complicated for them. If failing to understand something (at first!) put a person off programming altogether, there would be no programmers. – Blorgbeard Aug 26 '14 at 04:05