I have a list that is stored as a serialized string in one of my tables (I'm using the Azure Data Tables SDK). That's why I have two properties, one as a string and other as a list that is ignored and only used within our code.
public string VisitedNodes { get; private set; } = JsonConvert.SerializeObject(new List<string>());
[IgnoreDataMember]
public List<string> VisitedNodesList
{
get => JsonConvert.DeserializeObject<List<string>>(VisitedNodes);
set => VisitedNodes = JsonConvert.SerializeObject(value);
}
However, I simply can't manipulate this list easily because methods like .AddRange
or .Add
won't work. If I need to change its values I have to create an auxiliary object
var aux = VisitedNodesList;
aux.Add("node1");
VisitedNodesList = aux;
As this isn't what I indented to do at first, I suspect I might be doing something wrong or that there's a better way to store serialized values in a entity.
CodePudding user response:
What about this?
public string VisitedNodes { get; private set; } = JsonConvert.SerializeObject(VisitedNodesList);
private List<String> _visitedNodeList = new List<String>();
[IgnoreDataMember]
public List<string> VisitedNodesList
{
get => _visitedNodeList;
set => _VisitedNodeList = value;
}
CodePudding user response:
If you can change type of VisitNodesList
property, you can replace it to custom collection type inherited from Collection<T>
with overloaded ***Item()
methods.
Based on example from docs:
public class CollectionWithOnChangeAction<T> : Collection<T>
{
public Action? OnChange { get; set; }
protected override void InsertItem(int index, T item)
{
base.InsertItem(index, item);
OnChange?.Invoke();
}
protected override void SetItem(int index, T item)
{
base.SetItem(index, item);
OnChange?.Invoke();
}
protected override void RemoveItem(int index)
{
base.RemoveItem(index);
OnChange?.Invoke();
}
protected override void ClearItems()
{
base.ClearItems();
OnChange?.Invoke();
}
}
And then use it like this:
public class SomeClass
{
public string VisitedNodes { get; private set; } = JsonConvert.SerializeObject(new List<string>());
[IgnoreDataMember] private CollectionWithOnChangeAction<string> _visitedNodesList;
[IgnoreDataMember]
public CollectionWithOnChangeAction<string> VisitedNodesList
{
get => _visitedNodesList;
set
{
_visitedNodesList = value;
_visitedNodesList.OnChange = OnChange;
OnChange();
}
}
public SomeClass()
{
VisitedNodesList = new CollectionWithOnChangeAction<string>();
}
private void OnChange()
{
VisitedNodes = JsonConvert.SerializeObject(VisitedNodesList);
}
}
public class Tests
{
[Fact]
public void Test()
{
SomeClass someClass = new();
someClass.VisitedNodesList.Add("node1");
someClass.VisitedNodesList.Add("node2");
someClass.VisitedNodesList.Add("node3");
someClass.VisitedNodesList.Add("node4");
Assert.Equal(JsonConvert.SerializeObject(new List<string> { "node1", "node2", "node3", "node4" }),
someClass.VisitedNodes);
someClass.VisitedNodesList.Insert(2, "insert node");
Assert.Equal(JsonConvert.SerializeObject(new List<string>
{
"node1",
"node2",
"insert node",
"node3",
"node4"
}), someClass.VisitedNodes);
someClass.VisitedNodesList[4] = "set node";
Assert.Equal(JsonConvert.SerializeObject(new List<string>
{
"node1",
"node2",
"insert node",
"node3",
"set node"
}), someClass.VisitedNodes);
someClass.VisitedNodesList.Remove("node2");
Assert.Equal(JsonConvert.SerializeObject(new List<string> { "node1", "insert node", "node3", "set node" }),
someClass.VisitedNodes);
someClass.VisitedNodesList.RemoveAt(0);
Assert.Equal(JsonConvert.SerializeObject(new List<string> { "insert node", "node3", "set node" }),
someClass.VisitedNodes);
someClass.VisitedNodesList = new CollectionWithOnChangeAction<string> { "new node1", "new node2" };
Assert.Equal(JsonConvert.SerializeObject(new List<string> { "new node1", "new node2" }),
someClass.VisitedNodes);
}
}