J'essaie de faire quelque chose qui semble être facile, mais ça ne marche pas. J'ai un dictionnaire d'objets avec une clé int. Au sein des objets, j'ai une propriété, PositionInEvent, que je veux faire correspondre la clé du dictionnaire en son sein. Il semble que cela devrait être une simple opération en boucle, mais cela ne fonctionne pas. Voici ce que j'ai:Pourquoi les éléments du dictionnaire sont-ils ajoutés par référence en C#?
private void ensurePositions(ref Dictionary<int, DisplayUnit> dict)
{
var keys = dict.Keys.ToArray();
foreach(var key in keys)
{
dict[key].PositionInEvent = key;
}
}
Quand je lance ce sur un dictionnaire de 5 objets avec les touches de 0-4 (il ne sera pas toujours séquentielle comme ça, mais je suis tester l'unité), la PositionInEvent propriété sur chaque élément de l'événement a une valeur de 4. Chaque seul. Pourquoi???? Comment puis-je faire ce que j'essaie de faire. Il semble que cela devrait être simple.
Mise à jour:
Il a été demandé que je montre comment DisplayUnit est déclarée, instancié et ajouté au dictionnaire.
est ici la déclaration de classe (je l'ai fait sortir les choses sans rapport avec l'instanciation et la propriété, je travaille avec ici):
/// <summary>
/// This is the base display unit from which all other units are derived.
/// </summary>
public abstract class DisplayUnit
{
/// <summary>
/// Initializes a new instance of the <see cref="AbstractClasses.DisplayUnit"/> class.
/// </summary>
protected DisplayUnit (Dictionary<string,string> attributes)
{
this.Id = Guid.NewGuid();
tryApplyAttributes(attributes);
}
protected DisplayUnit(Guid id, Dictionary<string,string> attributes)
{
this.Id = id;
tryApplyAttributes(attributes);
}
private void tryApplyAttributes(Dictionary<string,string> attributes)
{
string name;
attributes.TryGetValue("Name", out name);
Name = name;
string description;
attributes.TryGetValue("Description", out description);
Description = description;
string dateTime;
attributes.TryGetValue ("DateCreated", out dateTime);
DateTime date;
DateTime.TryParse(dateTime,out date);
DateCreated = date;
string guid;
attributes.TryGetValue("AssociatedEvent", out guid);
Guid id;
Guid.TryParse(guid, out id);
AssociatedEvent = id;
string group;
attributes.TryGetValue("GroupId", out group);
Guid groupId;
var groupSet = Guid.TryParse(group, out groupId);
string posInGroup;
attributes.TryGetValue("PositionInGroup", out posInGroup);
int intPos;
var posSet = int.TryParse(posInGroup, out intPos);
if (posSet && groupSet)
UnitGroup = new DisplayUnitGrouping (intPos, groupId);
string pos;
attributes.TryGetValue("PositionInEvent", out pos);
int position;
int.TryParse (pos, out position);
PositionInEvent = position;
}
public Guid Id {
get;
private set;
}
private int _positionInEvent;
public int PositionInEvent {
get{
return _positionInEvent;
}
set {
if (value < 0) {
throw new NegativePositionException ("Position of DisplayUnit must be positive.");
}
_positionInEvent = value;
}
}
}
TextUnit est la classe que je suis en fait utiliser, ce qui dérive de DisplayUnit:
public class TextUnit : DisplayUnit
{
public string Text {
get;
set;
}
public TextUnit (Dictionary<string, string> attributes) : base (attributes)
{
SetAttributes (attributes);
Plugin = new FaithEngage.Plugins.DisplayUnits.TextUnitPlugin.TextUnitPlugin();
}
public TextUnit (Guid id, Dictionary<string, string> attributes) : base (id, attributes)
{
SetAttributes (attributes);
}
#region implemented abstract members of DisplayUnit
public override void SetAttributes (Dictionary<string, string> attributes)
{
string text;
attributes.TryGetValue ("text", out text);
Text = text;
}
#endregion
}
Le dictionnaire sur lequel on agit provient d'ici. _duRepo
est un dépôt falsifié (voir le code ci-dessous).
public Dictionary<int, DisplayUnit> GetByEvent(Guid eventId)
{
try {
var returnDict = new Dictionary<int,DisplayUnit>();
var dict = _duRepo.GetByEvent(eventId);
if (dict == null)
return null;
foreach(var key in dict.Keys)
{
var du = _factory.ConvertFromDto(dict [key]);
if(du == null) continue;
returnDict.Add (key, du);
}
ensurePositions(ref returnDict);
return returnDict;
} catch (RepositoryException ex) {
throw new RepositoryException ("There was a problem accessing the DisplayUnitRepository", ex);
}
}
Tout cela vient de ce test unitaire (que je ne peux pas passer, et je ne sais pas pourquoi):
[Test]
public void GetByEvent_ValidEventId_ReturnsDictOfEvents()
{
var dict = new Dictionary<int,DisplayUnitDTO>();
for(var i = 0; i < 5; i++)
{
dict.Add(i, new DisplayUnitDTO());
}
var repo = A.Fake<IDisplayUnitsRepository>();
A.CallTo(() => repo.GetByEvent(VALID_GUID)).Returns(dict);
A.CallTo(() => _fctry.ConvertFromDto(null))
.WithAnyArguments()
.Returns(
new TextUnit(
new Dictionary<string,string>(){
{ "Text", "This is my Text" }
}
)
);
A.CallTo (() => _container.Resolve<IDisplayUnitsRepository>()).Returns(repo);
var mgr = new DisplayUnitsRepoManager(_container);
var duDict = mgr.GetByEvent(VALID_GUID);
Assert.That(duDict, Is.InstanceOf(typeof(Dictionary<int,DisplayUnit>)));
Assert.That(duDict, Is.Not.Null);
Assert.That(duDict.Count == 5);
foreach(var key in duDict.Keys)
{
Assert.That(duDict[key].PositionInEvent == key);
}
}
Comment créez-vous l'objet Unité d'affichage. Il semble que les quatre éléments du dictionnaire référencent la même instance DusplayUnit. – ShuberFu
Pouvez-vous montrer la déclaration de la 'DisplayUnit' aussi? btw: le mot-clé 'ref' semble inutile puisque vous changez seulement le contenu de ce dictionnaire, pas la référence elle-même, mais cela ne devrait pas être l'erreur. –
J'ai créé un simple JS Fiddle pour cela: https://dotnetfiddle.net/T1Z9PW. Je suis d'accord avec Sterling W que votre construction du dictionnaire est suspecte. – syazdani