I have a method that is called by thread. I am having problem with the dictionary that item already exist exception. what could be the possible solution. i have provided my scenario code and changes made to overcome the problem.
The method is called by the thread.
public Item[] GetFolders()
{
Dictionary<long,string> values = new Dictionary<long,string> ();
Dictionary<long,string> values2 = new Dictionary<long,string> ();
var remotePage = service.GetPage();
foreach(var remotesummary in remotePage)
{
values2.Add(remotesummary.id, remotesummary.name);
}
foreach(var remotesummary in remotePage)
{
values.Add(remotesummary.id, remotesummary.name);
}
}
Modified code to overcome the exception ""
public Item[] GetFolders()
{
Dictionary<long,string> values = new Dictionary<long,string> ();
Dictionary<long,string> values2 = new Dictionary<long,string> ();
foreach(var remotesummary in remotePage)
{
var remt = remotesummary;
values.Add(remotesummary.id, remotesummary.name);
}
foreach(var remotesummary in remotePage)
{
var remt = remotesummary;
values2.Add(rem.id, rem.name);
}
}
You can check if that key already exists before inserting it. Add this to your code
if (dict.ContainsKey(key)) { ... }
plase note that you need to change dict for your variable name :D
Related
i have a gridview
INSEE1 Commune
------ -------
10002 AILLEVILLE
10003 BRUN
i have a script that return a list of object.
List<object> Temp = ASPxGridView_Insee.GetSelectedFieldValues("INSEE1");
my Temp is a list of object of INSSE1 that i have selected.
but now i add Commune also, so my script become:
List<object> Temp = ASPxGridView_Insee.GetSelectedFieldValues("INSEE1","Commune");
and my Temp is list of object of INSEE1 and Commune look at image:
how can i acces 10002 and AILLEVILLE ?
i have try with cast it of my Pers_INSEE class:
public class Pers_InseeZone
{
string _Code_Insee;
public string Code_Insee
{
get { return _Code_Insee; }
set { _Code_Insee = value; }
}
string _Commune;
public string Commune
{
get { return _Commune; }
set { _Commune = value; }
}
}
foreach (var oItem in Temp )
{
Pers_InseeZone o = (Pers_InseeZone)oItem;
}
but I not work, I can not cast it.
I have tried like this:
foreach (var oItem in Temp )
{
var myTempArray = oItem as IEnumerable;
foreach (var oItem2 in myTempArray)
{
string res= oItem2.ToString();
....
the value of res = 10002, but how can I get the value of AILEVILLE ?
the value of Temp[0].GetType(); is:
Thanks in advance
Ok I thought so, so as already mentioned in the comments you have a array of objects inside each object so you need to cast first every object in your list into an array of objects: object[] then you can access each part. Here is an example that recreates your problem:
object[] array = new object[] {10002, "AILEEVILLE"};
List<object> Temp = new List<object> {array};
And the solution:
// cast here so that the compiler knows that it can be indexed
object [] obj_array = Temp[0] as object[];
List<Pers_InseeZone> persList = new List<Pers_InseeZone>();
Pers_InseeZone p = new Pers_InseeZone()
{
Code_Insee = obj_array[0].ToString(),
Commune = obj_array[1].ToString()
};
persList.Add(p);
Applied to your code it would look something like this:
List<object> Temp = ASPxGridView_Insee.GetSelectedFieldValues("INSEE1","Commune");
List<Pers_InseeZone> persList = new List<Pers_InseeZone>();
foreach (object oItem in Temp )
{
object [] obj_array = oItem as object[];
Pers_InseeZone p = new Pers_InseeZone()
{
Code_Insee = obj_array[0].ToString(),
Commune = obj_array[1].ToString()
};
persList.Add(p);
}
The problem is down to the fact your class doesn't match the same structure as the data you are getting, so it can't be cast into it.
Instead why don't you just iterate over the results and build a new instance of the class?
var tempList = new List<Pers_InseeZone>();
foreach (var oItem in Temp)
{
tempList.Add(new Pers_InseeZone(oItem[0], oItem[1]));
}
You will need to add a constructor to your Pers_InseeZone class, and assign the variables there.
I am trying to use NRefactory to modify an existing piece of C# code. I have tried to use the method described in this article. I'm getting an exception complaining about duplicate changes. Can someone point out what I am doing wrong, and maybe point me in the right direction?
I have the following section of code:
// contains the source code that needs to be modified
var text = "...";
// is the name of the file in which the target class exists
var fileName = "Foo";
// is the name of the target class
var className = "Foo.cs";
// FormattingOptions and TextEditorOptions are properties available to
// the class containing this code...
var parser = new CSharpParser();
var syntaxTree = parser.Parse(text, fileName);
syntaxTree.Freeze();
var document = new StringBuilderDocument();
document.Text = syntaxTree.ToString(FormattingOptions);
using (var documentScript = new DocumentScript(document, FormattingOptions, TextEditorOptions))
{
var typeDeclarations = syntaxTree.Descendants.OfType<TypeDeclaration>().Where(typeDeclaration => typeDeclaration.Name == className);
var templateProviderDeclaration = typeDeclarations.SingleOrDefault();
if (templateProviderDeclaration != null)
{
var constructorDeclarations = templateProviderDeclaration.Descendants.OfType<ConstructorDeclaration>();
foreach (var constructorDeclaration in constructorDeclarations)
{
var assignmentExpressions = constructorDeclaration.Descendants.OfType<AssignmentExpression>();
foreach (var assignmentExpression in assignmentExpressions)
{
var leftExpression = assignmentExpression.Left;
if (leftExpression != null && leftExpression.ToString(FormattingOptions) == "this.templates")
{
var rightExpression = assignmentExpression.Right;
foreach (var arrayInitializerExpression in rightExpression.Children.OfType<ArrayInitializerExpression>())
{
// uses AddTemplate(), which is an extension method
// which takes in an expression and modifies it, and
// returns an expression
var newExpression = ((ArrayInitializerExpression)arrayInitializerExpression).AddTemplate();
documentScript.Replace(arrayInitializerExpression, newExpression);
}
}
}
}
}
// text retrieved here is *clobbered*, by a few characters
text = documentScript.CurrentDocument.Text;
}
Other Code...
public static class ExtensionMethods
{
public static ArrayInitializerExpression AddTemplate(this ArrayInitializerExpression expression)
{
// TODO : will modify the AST for the target expression
return (ArrayInitializerExpression)expression.Clone();
}
}
Update:
I am trying to change a line like this:
this.templates = new Dictionary<string, ITemplate>
{
{ "Foo", new FooTemplate() }
};
to:
this.templates = new Dictionary<string, ITemplate>
{
{ "Foo", new FooTemplate() },
{ "Bar", new BarTemplate() }
};
For the purposes of this question, the exact specifics of the change I am trying to make aren't important though. I suspect that I have something not constructed quite correctly, but I cannot figure out if that's the issue.
In c# I have 2 lists.
First List is like so:
respondent.PrescreenerResponses[i].Response[j] = {[12, some response]}
Second List is like so:
projects.Prescreeners[i].Questions[j] = {Prescreener Questions: Question}
What I want to do is create one list probably like:
Prescreeners[i].Responses[j]
Prescreeners[i].Questions[j]
My code though is somehow wrong:
foreach (var screener in respondent.PreScreenerResponses)
{
var responses = screener;
}
foreach (var screener in project.PreScreeners)
{
var questions = screener;
}
List<string> prescreenerResponses = new List<string>();
prescreenerResponses.Add(questions);
It tells me questions does not exist in the current context. Same goes for responses when I try to use it. I am pretty sure it the wrong data type but not sure what else it would be?
I am pretty sure it the wrong data type
No, it's scope. You declare the var responses and var questions in their respective foreach block. As soon as control leaves those blocks, the variables don't exist anymore.
Declare them first:
IEnumerable<PrescreenerResponses> responses = new List<PrescreenerResponses>;
foreach (...)
{
responses.Add(...)
}
Anyway you can also call AddRange() if you declase responses as List, so you can skip the loop:
responses.AddRange(respondent.PreScreenerResponses);
And it's even more advisable to create a DTO:
class QuestionAndAnswer
{
public PreScreener Question { get; set; }
public PreScreenerResponse Response { get; set; }
}
And use a loop with a counter to fill a List<QuestionAndAnswer>:
var result = new List<QuestionAndAnswer>();
for (int i = 0; i < projects.Prescreeners.Count; i++)
{
result.Add(new QuestionAndAnswer
{
Question = projects.Prescreeners[i],
Answer = respondent.PrescreenerResponses[i],
});
}
Try it like this
List<string> prescreenerResponses = new List<string>();
foreach (var screener in respondent.PreScreenerResponses)
{
var responses = screener;
}
foreach (var screener in project.PreScreeners)
{
prescreenerResponses.Add(screener);
}
You are accessing variable "questions" which is declared outside the scope,
Try this:
List<string> prescreenerResponses = new List<string>();
foreach (var screener in respondent.PreScreenerResponses)
{
var responses = screener;
}
foreach (var screener in project.PreScreeners)
{
var questions = screener;
prescreenerResponses.Add(questions);
}
It´s because 'questions' is declared inside your loop. You could try the code below:
private class QuestionAndResponses
{
public List<Response> Responses {get;set;}
public List<Question> Questions {get;set;}
}
List<QuestionAndResponses> prescreenerResponses = new List<QuestionAndResponses>();
for (var i = 0; i < project.preScreeners.Count(); i++)
{
prescreenerResponses.Add(new QuestionAndResponses ()
{
Responses = new List<Response>(project.preScreenerResponses[i].Response),
Questions = new List<Question>(project.preScreeners[i].Questions)
});
}
I'm trying to write to a model for the first time to use in my view: the first time I write to the model I get an ArgumentOutOfRangeException.
Getting error on first write to array:
private IAdditionalQuestionsService _service;
private SelectedAdditionalQuestionAnswerModel _model;
private void InitializeController()
{
_service = GetObject<IAdditionalQuestionsService>();
//GetPageHeaderText(inst);
ViewBag.GetPageTitle = "Additional Questions";
}
[HttpGet]
public virtual ActionResult Edit()
{
Institution inst = _service.GetInstitution(State.GetInstitutionRecordId());
_model = GetObject<SelectedAdditionalQuestionAnswerModel>();
_model.AddQuestAnswModel = new List<AdditionalQuestionAnswerModel>();
GetPageConfiguration1(inst);
return View(_model);
}
AdditionalQuestionAnswerModel m = GetObject<AdditionalQuestionAnswerModel>();
int c = 0;
foreach (var x in inst.AdditionalQuestions)
{
foreach (var y in x.AdditionalQuestionAnswers)
{
// Error is happening on next line *************
_model.AddQuestAnswModel[c].QuestionText = x.QuestionText;
_model.AddQuestAnswModel[c].InstitutionId = x.InstitutionId;
_model.AddQuestAnswModel[c].AdditionalQuestionId = x.Id;
_model.AddQuestAnswModel[c].AnswerText = y.AnswerText;
_model.AddQuestAnswModel[c].IsSelected = false;
c++;
}
}
You can't use _model.AddQuestAnswModel[c] because you never added any items to your list.
Instead of that, create a new object and set its values and then add the item to your list.
Something like this:
AdditionalQuestionAnswerModel newItem = new AdditionalQuestionAnswerModel();
//set the values here to newItem
_model.AddQuestAnswModel.Add(newItem);
You're firstly instantiating your list
_model.AddQuestAnswModel = new List<AdditionalQuestionAnswerModel>();
then you try to access to the first element
_model.AddQuestAnswModel[c] // c == 0
without adding any element to the list.
Add an element before trying to access to a list by index, or more simple:
foreach (var y in x.AdditionalQuestionAnswers)
{
AdditionalQuestionAnswerModel newObj = new AdditionalQuestionAnswerModel
{
QuestionText = x.QuestionText;
InstitutionId = x.InstitutionId;
AdditionalQuestionId = x.Id;
AnswerText = y.AnswerText;
IsSelected = false;
};
_model.AddQuestAnswModel.Add(newObj);
}
Ir means that there no item in your _model.AddQuestAnswModel at the indicated postition, and from your code, I see that _model.AddQuestAnswModel has only be initiated with new List<AdditionalQuestionAnswerModel>(), so it does not contain items (unless you're doing it in the contructor).
You need to fill it like so :
_model.AddQuestAnswModel.Add(item);
I have an app that creates ContactList Objects and adds them to a Dictionary collection. My ContactList objects have a property called AggLabels which is a collection of AggregatedLabel objects containg Name and Count properties. What I am trying to do is change the "else" case of my code snippet so that before adding a new AggregatedLabel it will check whether the AggLabel.Name exists in the AggregatedLabel collection and if this is true it will not add the AggLabel.Name again. Instead it will add the value of AggLabel.Count (type int) to the existing AggregatedLabel object. So for an existing object, if the first Count value was 3 and the second value is 2 then the new Count value should be 5. In simple terms I want to have unique AggLabel Names and add together the Counts where the Names are the same. Hope that makes sense - would appreciate any help. Thanks!
Code snippet
Dictionary<int, ContactList> myContactDictionary = new Dictionary<int, ContactList>();
using (DB2DataReader dr = command.ExecuteReader())
{
while (dr.Read())
{
int id = Convert.ToInt32(dr["CONTACT_LIST_ID"]);
if (!myContactDictionary.ContainsKey(id))
{
ContactList contactList = new ContactList();
contactList.ContactListID = id;
contactList.ContactListName = dr["CONTACT_LIST_NAME"].ToString();
//contactList.AggLabels = new ObservableCollection<AggregatedLabel>() { new AggregatedLabel() { Name = dr["LABEL_NAME"].ToString(), Count = Convert.ToInt32(dr["LABEL_COUNT"])}};
contactList.AggLabels = new ObservableCollection<AggregatedLabel>()
{
new AggregatedLabel()
{
Name = dr["LABEL_NAME"].ToString(),
Count = Convert.ToInt32(dr["LABEL_COUNT"])
}
};
myContactDictionary.Add(id, contactList);
}
else
{
ContactList contactList = myContactDictionary[id];
contactList.AggLabels.Add(
new AggregatedLabel()
{
Name = dr["LABEL_NAME"].ToString(),
Count = Convert.ToInt32(dr["LABEL_COUNT"])
}
);
}
}
}
There are two possible solutions I can think of:
1) Use a dictionary instead of the collection of aggregated labels the same way you do it for the contact dictionary. When yout use the name as key and the count as value, you can use the ContainsKey-Method to check whether the label already exists.
contactList.AggLabels = new Dictionary<string, int>();
...
else
{
ContactList contactList = myContactDictionary[id];
if (contactList.AggLabels.ContainsKey(dr["LABEL_NAME"].ToString()))
{
contactList.AggLabels[dr["LABEL_NAME"].ToString()] += Convert.ToInt32(dr["LABEL_COUNT"]);
}
else
{
contactList.AggLabels.Add(dr["LABEL_NAME"].ToString(), Convert.ToInt32(dr["LABEL_COUNT"]));
}
}
2) I you need to use the AggreagteLabel object you can use a loop to search throug all labels.
else
{
bool flagAggLabelFound = false;
ContactList contactList = myContactDictionary[id];
foreach(AggregateLabel aggLabel in contactList.AggLabels)
{
if(aggLabel.Name == dr["LABEL_NAME"].ToString())
{
aggLabel.Count += Convert.ToInt32(dr["LABEL_COUNT"]);
flagAggLabelFound = true;
break;
}
}
if (!flagAggLabelFound)
{
contactList.AggLabels.Add(
new AggregatedLabel()
{
Name = dr["LABEL_NAME"].ToString(),
Count = Convert.ToInt32(dr["LABEL_COUNT"])
}
);
}
}
I hope this helps.
I would try this:
ContactList contactList = myContactDictionary[id];
AggregateLabel existing = contactList.AggLabels.FirstOrDefault(
l => l.Name == dr["LABEL_NAME"].ToString()
);
if (existing == null) { contactList.AggLabels.Add(
new AggregatedLabel() {
Name = dr["LABEL_NAME"].ToString(),
Count = Convert.ToInt32(dr["LABEL_COUNT"])
}
);
}
else { existing.Count += Convert.ToInt32(dr["LABEL_COUNT"]); }
#extract these Aggregated Labels and put them in a separate Observable collection:
1) If you a Dictionary for storing the labels in the contact list, this should work:
ObservableCollection<AggregateLabel> copyOfAggregateLabels = new ObservableCollection<AggregateLabel>();
foreach (KeyValuePair<string, int> aggLabel in aggregateLabels)
{
copyOfAggregateLabels.Add(
new AggregatedLabel() {
Name = aggLabel.Key,
Count = aggLabel.Value
}
);
}
2) If you use an ObservableCollection of AggregateLabels, you get an AggregateLable instead of a KeyValuePair in the loop. The rest works the same way.
First I thought of something like:
ObservableCollection<AggregateLabel> copyOfAggregateLabels = new ObservableCollection<AggregateLabel>(aggregateLables);
But this way you get a new ObservableCollection, but the labels stored in the new collection are still referring to the same objects as the ones in the collection you copy.