I'm trying to make a collection class in C#












0












$begingroup$


As a side project i'm trying to remake one of my favorite games from the old days, moria/angband. I'm doing it from scratch and in C#. In order to store the inventory I have the following classes, Item and Items.



The Item Class is an abstract class that provides all the base properties and methods for an item in the game. Then I have other classes that inherit from it such as the Potion, Armor, or Weapon Classes.



Then I have the Items class which I want to be a collection of Items. This will be for the player's inventory, what the enemies carry as loot, and even a collection of items on a map square. Anywhere a collection of Items can exist, i'll use this collection.



I have defined it as such:



    public class Items
{

private Dictionary<string, Item> _inventory = new Dictionary<string, Item>();

public Dictionary<string, Item> Inventory
{
get
{
return _inventory;
}
set { }
}

public override string ToString()
{
string hold = "";
int i = 0;

foreach (var item in Inventory)
{
hold += "n" + i.ToString() + " " + item.ToString() + "n";
}

return hold;
}
}


I originally tried to just return the collection, but realized that it is probably bad practice to expose the actual reference and kind of defeats the purpose of encapsulating it. So I was going to modify it to maybe Clone it. However, I don't have access to the Values or Keys collections and since I don't implement IEnumerable, I can't foreach over it which is something that will happen alot. I was thinking I had to impliment IEnumerable:



I have the same issue with my Effects collection class. It is a collection of Effect objects. An effect is something that modifies the base condition of an object, be it the player(poison, fire resistance, etc) a weapon(frost damage effect, holy avenger, etc), and so on. So, I tried it.



public class Effects : IEnumerable
{

Dictionary<string, Effect> _effects = new Dictionary<string, Effect>();

public string Name
{
get
{
string result = "";
foreach (Effect eff in _effects.Values)
{
result += $" {eff.Name}";
}
return result;
}
}

public override string ToString()
{
string result = "";// "Effects:n";
foreach (var effect in _effects.Values)
{
result += $"nEffectName: {effect.Name.PadRight(20,' ')} Type: {effect.EffectType.ToString().PadRight(15,' ')} Magnitude: {effect.Magnitude} Duration: {effect.Duration} ";
}
return result;
}

public void AddEffect(Effect eff)
{
_effects.Add(eff.Name, eff);
}
public void AddEffect(EffectTypes effType, int magnitude)
{
Effect eff = new Effect();

eff.EffectType = effType;
eff.Magnitude = magnitude;
eff.Name = effType.ToString();

_effects.Add(eff.Name, eff);

}


// Implementation for the GetEnumerator method.

IEnumerator IEnumerable.GetEnumerator()
{
return _effects.GetEnumerator();
}
}


I still don't have access to simple things like Count and so on. I think the Effects collection is closer to what I need. What I need is this: I want both Items and Effects to behave exactly as if it were a dictionary from any other class using it. Each will have custom code methods and properties which I haven't included nor written many of which makes using just a vanilla dictionary problematic.



What is the best way to implement this?



Thanks,



Brian









share









$endgroup$

















    0












    $begingroup$


    As a side project i'm trying to remake one of my favorite games from the old days, moria/angband. I'm doing it from scratch and in C#. In order to store the inventory I have the following classes, Item and Items.



    The Item Class is an abstract class that provides all the base properties and methods for an item in the game. Then I have other classes that inherit from it such as the Potion, Armor, or Weapon Classes.



    Then I have the Items class which I want to be a collection of Items. This will be for the player's inventory, what the enemies carry as loot, and even a collection of items on a map square. Anywhere a collection of Items can exist, i'll use this collection.



    I have defined it as such:



        public class Items
    {

    private Dictionary<string, Item> _inventory = new Dictionary<string, Item>();

    public Dictionary<string, Item> Inventory
    {
    get
    {
    return _inventory;
    }
    set { }
    }

    public override string ToString()
    {
    string hold = "";
    int i = 0;

    foreach (var item in Inventory)
    {
    hold += "n" + i.ToString() + " " + item.ToString() + "n";
    }

    return hold;
    }
    }


    I originally tried to just return the collection, but realized that it is probably bad practice to expose the actual reference and kind of defeats the purpose of encapsulating it. So I was going to modify it to maybe Clone it. However, I don't have access to the Values or Keys collections and since I don't implement IEnumerable, I can't foreach over it which is something that will happen alot. I was thinking I had to impliment IEnumerable:



    I have the same issue with my Effects collection class. It is a collection of Effect objects. An effect is something that modifies the base condition of an object, be it the player(poison, fire resistance, etc) a weapon(frost damage effect, holy avenger, etc), and so on. So, I tried it.



    public class Effects : IEnumerable
    {

    Dictionary<string, Effect> _effects = new Dictionary<string, Effect>();

    public string Name
    {
    get
    {
    string result = "";
    foreach (Effect eff in _effects.Values)
    {
    result += $" {eff.Name}";
    }
    return result;
    }
    }

    public override string ToString()
    {
    string result = "";// "Effects:n";
    foreach (var effect in _effects.Values)
    {
    result += $"nEffectName: {effect.Name.PadRight(20,' ')} Type: {effect.EffectType.ToString().PadRight(15,' ')} Magnitude: {effect.Magnitude} Duration: {effect.Duration} ";
    }
    return result;
    }

    public void AddEffect(Effect eff)
    {
    _effects.Add(eff.Name, eff);
    }
    public void AddEffect(EffectTypes effType, int magnitude)
    {
    Effect eff = new Effect();

    eff.EffectType = effType;
    eff.Magnitude = magnitude;
    eff.Name = effType.ToString();

    _effects.Add(eff.Name, eff);

    }


    // Implementation for the GetEnumerator method.

    IEnumerator IEnumerable.GetEnumerator()
    {
    return _effects.GetEnumerator();
    }
    }


    I still don't have access to simple things like Count and so on. I think the Effects collection is closer to what I need. What I need is this: I want both Items and Effects to behave exactly as if it were a dictionary from any other class using it. Each will have custom code methods and properties which I haven't included nor written many of which makes using just a vanilla dictionary problematic.



    What is the best way to implement this?



    Thanks,



    Brian









    share









    $endgroup$















      0












      0








      0





      $begingroup$


      As a side project i'm trying to remake one of my favorite games from the old days, moria/angband. I'm doing it from scratch and in C#. In order to store the inventory I have the following classes, Item and Items.



      The Item Class is an abstract class that provides all the base properties and methods for an item in the game. Then I have other classes that inherit from it such as the Potion, Armor, or Weapon Classes.



      Then I have the Items class which I want to be a collection of Items. This will be for the player's inventory, what the enemies carry as loot, and even a collection of items on a map square. Anywhere a collection of Items can exist, i'll use this collection.



      I have defined it as such:



          public class Items
      {

      private Dictionary<string, Item> _inventory = new Dictionary<string, Item>();

      public Dictionary<string, Item> Inventory
      {
      get
      {
      return _inventory;
      }
      set { }
      }

      public override string ToString()
      {
      string hold = "";
      int i = 0;

      foreach (var item in Inventory)
      {
      hold += "n" + i.ToString() + " " + item.ToString() + "n";
      }

      return hold;
      }
      }


      I originally tried to just return the collection, but realized that it is probably bad practice to expose the actual reference and kind of defeats the purpose of encapsulating it. So I was going to modify it to maybe Clone it. However, I don't have access to the Values or Keys collections and since I don't implement IEnumerable, I can't foreach over it which is something that will happen alot. I was thinking I had to impliment IEnumerable:



      I have the same issue with my Effects collection class. It is a collection of Effect objects. An effect is something that modifies the base condition of an object, be it the player(poison, fire resistance, etc) a weapon(frost damage effect, holy avenger, etc), and so on. So, I tried it.



      public class Effects : IEnumerable
      {

      Dictionary<string, Effect> _effects = new Dictionary<string, Effect>();

      public string Name
      {
      get
      {
      string result = "";
      foreach (Effect eff in _effects.Values)
      {
      result += $" {eff.Name}";
      }
      return result;
      }
      }

      public override string ToString()
      {
      string result = "";// "Effects:n";
      foreach (var effect in _effects.Values)
      {
      result += $"nEffectName: {effect.Name.PadRight(20,' ')} Type: {effect.EffectType.ToString().PadRight(15,' ')} Magnitude: {effect.Magnitude} Duration: {effect.Duration} ";
      }
      return result;
      }

      public void AddEffect(Effect eff)
      {
      _effects.Add(eff.Name, eff);
      }
      public void AddEffect(EffectTypes effType, int magnitude)
      {
      Effect eff = new Effect();

      eff.EffectType = effType;
      eff.Magnitude = magnitude;
      eff.Name = effType.ToString();

      _effects.Add(eff.Name, eff);

      }


      // Implementation for the GetEnumerator method.

      IEnumerator IEnumerable.GetEnumerator()
      {
      return _effects.GetEnumerator();
      }
      }


      I still don't have access to simple things like Count and so on. I think the Effects collection is closer to what I need. What I need is this: I want both Items and Effects to behave exactly as if it were a dictionary from any other class using it. Each will have custom code methods and properties which I haven't included nor written many of which makes using just a vanilla dictionary problematic.



      What is the best way to implement this?



      Thanks,



      Brian









      share









      $endgroup$




      As a side project i'm trying to remake one of my favorite games from the old days, moria/angband. I'm doing it from scratch and in C#. In order to store the inventory I have the following classes, Item and Items.



      The Item Class is an abstract class that provides all the base properties and methods for an item in the game. Then I have other classes that inherit from it such as the Potion, Armor, or Weapon Classes.



      Then I have the Items class which I want to be a collection of Items. This will be for the player's inventory, what the enemies carry as loot, and even a collection of items on a map square. Anywhere a collection of Items can exist, i'll use this collection.



      I have defined it as such:



          public class Items
      {

      private Dictionary<string, Item> _inventory = new Dictionary<string, Item>();

      public Dictionary<string, Item> Inventory
      {
      get
      {
      return _inventory;
      }
      set { }
      }

      public override string ToString()
      {
      string hold = "";
      int i = 0;

      foreach (var item in Inventory)
      {
      hold += "n" + i.ToString() + " " + item.ToString() + "n";
      }

      return hold;
      }
      }


      I originally tried to just return the collection, but realized that it is probably bad practice to expose the actual reference and kind of defeats the purpose of encapsulating it. So I was going to modify it to maybe Clone it. However, I don't have access to the Values or Keys collections and since I don't implement IEnumerable, I can't foreach over it which is something that will happen alot. I was thinking I had to impliment IEnumerable:



      I have the same issue with my Effects collection class. It is a collection of Effect objects. An effect is something that modifies the base condition of an object, be it the player(poison, fire resistance, etc) a weapon(frost damage effect, holy avenger, etc), and so on. So, I tried it.



      public class Effects : IEnumerable
      {

      Dictionary<string, Effect> _effects = new Dictionary<string, Effect>();

      public string Name
      {
      get
      {
      string result = "";
      foreach (Effect eff in _effects.Values)
      {
      result += $" {eff.Name}";
      }
      return result;
      }
      }

      public override string ToString()
      {
      string result = "";// "Effects:n";
      foreach (var effect in _effects.Values)
      {
      result += $"nEffectName: {effect.Name.PadRight(20,' ')} Type: {effect.EffectType.ToString().PadRight(15,' ')} Magnitude: {effect.Magnitude} Duration: {effect.Duration} ";
      }
      return result;
      }

      public void AddEffect(Effect eff)
      {
      _effects.Add(eff.Name, eff);
      }
      public void AddEffect(EffectTypes effType, int magnitude)
      {
      Effect eff = new Effect();

      eff.EffectType = effType;
      eff.Magnitude = magnitude;
      eff.Name = effType.ToString();

      _effects.Add(eff.Name, eff);

      }


      // Implementation for the GetEnumerator method.

      IEnumerator IEnumerable.GetEnumerator()
      {
      return _effects.GetEnumerator();
      }
      }


      I still don't have access to simple things like Count and so on. I think the Effects collection is closer to what I need. What I need is this: I want both Items and Effects to behave exactly as if it were a dictionary from any other class using it. Each will have custom code methods and properties which I haven't included nor written many of which makes using just a vanilla dictionary problematic.



      What is the best way to implement this?



      Thanks,



      Brian







      c# object-oriented iterator collections





      share












      share










      share



      share










      asked 6 mins ago









      Brian PleshekBrian Pleshek

      92




      92






















          0






          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f213490%2fim-trying-to-make-a-collection-class-in-c%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f213490%2fim-trying-to-make-a-collection-class-in-c%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Сан-Квентин

          8-я гвардейская общевойсковая армия

          Алькесар