I'm trying to make a collection class in C#
$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
c# object-oriented iterator collections
$endgroup$
add a comment |
$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
c# object-oriented iterator collections
$endgroup$
add a comment |
$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
c# object-oriented iterator collections
$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
c# object-oriented iterator collections
asked 6 mins ago
Brian PleshekBrian Pleshek
92
92
add a comment |
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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