How to add object to list item in c# - c#

I have following classes:
public class QualifyResponse
{
List<ProviderQualifyResponse> _providerList = new List<ProviderQualifyResponse>();
public List<ProviderQualifyResponse> ProviderList
{
get { return _providerList; }
set { _providerList = value; }
}
}
public class ProviderQualifyResponse
{
private string _providerCode = string.Empty;
public string ProviderCode
{
get { return _providerCode; }
set { _providerCode = value; }
}
private List<QuestionGroup> _questionGroupList = new List<QuestionGroup>();
public List<QuestionGroup> QuestionGroupList
{
get { return _questionGroupList; }
set { _questionGroupList = value; }
}
}
I have QualifyResponse object which is populated with ProviderQualifyResponse but QuestionGroupList is empty. Now I want to fill QuestionGroupList. When I try to do it like this:
QualifyResponse qualifyResponse = response;
qualifyResponse.ProviderList.QuestionGroupList = new List<DataTypes.BuyFlow.Entities.QuestionGroup>();
I get error:
System.Collections.Generic.List' does not
contain a definition for 'QuestionGroupList' and no extension method
'QuestionGroupList' accepting a first argument of type
'System.Collections.Generic.List' could be
found (are you missing a using directive or an assembly reference?)
How can I add a List<QuestionGroup> to my qualifyResponse.ProviderList?

The error is this expression:
qualifyResponse.ProviderList.QuestionGroupList
ProviderList is of type List. You'll have to change it so you populate the correct item. Something like this:
int index = ...;
qualifyResponse.ProviderList[index].QuestionGroupList = ...

Problem is that QuestionGroupList is property of class ProviderQualifyResponse and if you want to add List, you need to assign it to property of object.
Example how to do that for all providers:
QualifyResponse qualifyResponse = response;
foreach(var provider in qualifyResponse.ProviderList)
{
provider.QuestionGroupList = new List<DataTypes.BuyFlow.Entities.QuestionGroup>();
}

Given that qualifyResponse.ProviderList is of type List<ProviderQualifyResponse>, you are trying to access List.QuestionGroupList, which doesn't exist as the error states.
You'll either need to iterate through the instances in the list to access the instance properties, if that's your intention, or select an instance from the list you wish to instantiate.
QualifyResponse qualifyResponse = response;
foreach (var providerQualifyResponse in qualifyResponse.ProviderList)
{
providerQualifyResponse.QuestionGroupList = new List<DataTypes.BuyFlow.Entities.QuestionGroup>();
}

Related

How to get a property value of a class defined inside of another class through a reflection

I have a MerchantWSBO and MerchantWSVO classes.
MerchantWSBO has a property of a type of MerchantWSVO.
I need to get a value of the property of a MerchantWSVO.
So, I have a code defining both classes(classes are coming through a WebReference from a 3rd party)
public MerchantWSBO {
private MerchantWSVO overviewField;
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public MerchantWSVO overview {
get {
return this.overviewField;
}
set {
this.overviewField = value;
}
}
}
public MerchantWSVO{
private System.Nullable<bool> discoverRetainedField;
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool discoverRetainedSpecified {
get {
return this.discoverRetainedFieldSpecified;
}
set {
this.discoverRetainedFieldSpecified = value;
}
}
}
I have the following method where I need to get the property value of dicoverRetained using reflection:
private string ClassToXML(Object classObject)
{
MerchantTest mt = new MerchantTest();
if(classObject is MerchantWSBO)
{
classObject.GetType().GetProperty("overviewField").GetValue(new MerchantWSVO, null);
mt.overview.discoverRetained = //need to get the value
}
var myString = new System.IO.StringWriter();
var serializer = new XmlSerializer(classObject.GetType());
serializer.Serialize(myString, classObject);
return myString.ToString();
}
Based on a parameter classObject which in this case can be of two types, I need to get a value from a property.
How can I do that?
You don't need reflection at all, simply cast the object to the correct type. Pattern matching helps here.
if(classObject is MerchantWSBO wsbo)
{
Console.WriteLine(wsbo.overview.discoverRetained);
}
or on older C# versions:
var wsbo = classObject as MerchantWSBO;
if(wsbo != null)
{
Console.WriteLine(wsbo.overview.discoverRetained);
}

Object Reference not set when using PrinterSettings.StringCollection

I am attempting to list the currently installed printers using PrinterSettings.StringCollection. However, I get this error:
Object Reference not set to an instance of an object
Code is as follows:
namespace DropDownLibrary
{
public class DropDownExample : DSDropDownBase
{
public DropDownExample() : base("item") { }
public static PrinterSettings.StringCollection InstalledPrinters { get; }
public override void PopulateItems()
{
// The Items collection contains the elements
// that appear in the list.
Items.Clear();
// Create a number of DynamoDropDownItem objects
// to store the items that we want to appear in our list.
var newItems = new List<DynamoDropDownItem>();
{
foreach (String name in InstalledPrinters)
{
new DynamoDropDownItem("{0}", name);
}
};
Items.AddRange(newItems);
// Set the selected index to something other
// than -1, the default, so that your list
// has a pre-selection.
SelectedIndex = 0;
}
public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes)
{
// Build an AST node for the type of object contained in your Items collection.
var intNode = AstFactory.BuildIntNode((int)Items[SelectedIndex].Item);
var assign = AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), intNode);
return new List<AssociativeNode> { assign };
}
}
}
This is covered in this post. The 'Object reference not set to instance of an Object" error is caused by you trying to use a variable that is null. For instance, you can get a null reference error by doing:
object nullObject = null;
nullObject.ToString():
In your code, it doesn't look like the value for InstalledPrinters ever gets set.
Before your code reaches this line:
foreach (String name in InstalledPrinters)
It looks like you copy pasted this from this link:
public static PrinterSettings.StringCollection InstalledPrinters { get; }
This is a property on the PrinterSettings class that you can access. You should access it like so:
var installedPrinters = System.Drawing.Printing.PrinterSettings.InstalledPrinters;
foreach (String name in installedPrinters)

Error An explicit conversion exists C#, MVVM Light - LINQ

I am learning MVVM Light and the app I am working on has a functionality to search for event names. Here are my codes for filtering a ListBox as the user types into TextBox.
The error is: Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<NGO_Volunteer_Comm_Platform_v1._0.DataModel.Event>' to 'System.Collections.Generic.List<NGO_Volunteer_Comm_Platform_v1._0.DataModel.Event>'. An explicit conversion exists (are you missing a cast?)
ViewModel codes:
private static ObservableCollection<Event> _searchEventCollection = new ObservableCollection<Event>();
public static ObservableCollection<Event> SearchEventCollection
{
get { return _searchEventCollection; }
set { _searchEventCollection = value; }
}
//search from homepage event section
private RelayCommand _eventSearch;
/// <summary>
/// Gets the EventSearch.
/// </summary>
public RelayCommand EventSearch
{
get
{
return _eventSearch
?? (_eventSearch = new RelayCommand(
async () =>
{
SearchEventCollection.Clear();
var eventList = await App.MobileService.GetTable<Event>().ToListAsync();
foreach (Event ename in eventList)
{
SearchEventCollection.Add(new Event
{
Id = ename.Id,
EventName = ename.EventName,
Date = ename.Date,
Location = ename.Location,
Desc = ename.Desc
});
}
}));
}
}
private string filter;
public String Filter
{
get
{
return this.filter;
}
set
{
this.filter = value;
RaisePropertyChanged("SearchEventCollection");
}
}
public List<Event> FilteredNames
{
get
{
return (from name in SearchEventCollection where name.EventName.StartsWith(filter) select name);
}
}
public searchfromhomepageViewModel()
{
filter = "";
}
How do I resolve this error?
Use the ToList extension method to create a List<T> from an IEnumerable<T>:
public List<Event> FilteredNames
{
get
{
return (from name in SearchEventCollection where name.EventName.StartsWith(filter) select name).ToList();
}
}
Or change the type of the FilteredNames property to IEnumerable<Event>. Actually, that's probably a better idea. In general, you shouldn't expose concrete collection types publicly, because it doesn't let you return an instance of a different type if you need to change it later. Also, returning a List<T> seems to imply that you can modify the list. But since a new list is returned each time the property is called, modifying it will have no effect on the property, so it's misleading.

multi return type in c# methods

I have a (string, object) dictionary, object (class) has some values including data type which is defined by enum. I need a GetItemValue method that should return dictionary item's value. So return type must be the type which is defined in item object.
Class Item
{
String Name;
DataValueType DataType;
Object DataValue;
}
private Dictionary<string, Item> ItemList = new Dictionary<string, Item>();
void Main()
{
int value;
ItemList.Add("IntItem", new Item("IntItem", DataValueType.TInt, 123));
value = GetItemValue("IntItem"); // value = 123
}
What kind of solution can overcome this problem?
Best Regards,
You can use Generic Classes
Class Item<T>
{
String Name;
T DataTypeObject;
Object DataValue;
public T GetItemValue()
{
//Your code
return DataTypeObject;
}
}
A better solution would be to introduce an interface that you make all the classes implement. Note that the interface doesn't necessarily have to specify any behavior:
public interface ICanBePutInTheSpecialDictionary {
}
public class ItemTypeA : ICanBePutInTheSpecialDictionary {
// code for the first type
}
public class ItemTypeB : ICanBePutInTheSpecialDictionary {
// code for the second type
}
// etc for all the types you want to put in the dictionary
To put stuff in the dictionary:
var dict = new Dictionary<string, ICanBePutInTheSpecialDictionary>();
dict.add("typeA", new ItemTypeA());
dict.add("typeB", new ItemTypeB());
When you need to cast the objects to their specific types, you can either use an if-elseif-block, something like
var obj = dict["typeA"];
if (obj is ItemTypeA) {
var a = obj as ItemTypeA;
// Do stuff with an ItemTypeA.
// You probably want to call a separate method for this.
} elseif (obj is ItemTypeB) {
// do stuff with an ItemTypeB
}
or use reflection. Depending on how many choices you have, either might be preferrable.
If you have a 'mixed bag' you could do something like this...
class Item<T>
{
public String Name { get; set; }
public DataValueType DataType { get; set; }
public T DataValue { get; set; }
}
class ItemRepository
{
private Dictionary<string, object> ItemList = new Dictionary<string, object>();
public void Add<T>(Item<T> item) { ItemList[item.Name] = item; }
public T GetItemValue<T>(string key)
{
var item = ItemList[key] as Item<T>;
return item != null ? item.DataValue : default(T);
}
}
and use it like...
var repository = new ItemRepository();
int value;
repository.Add(new Item<int> { Name = "IntItem", DataType = DataValueType.TInt, DataValue = 123 });
value = repository.GetItemValue<int>("IntItem");
If you have just a couple types - you're better off with Repository<T>.
I found a solution exactly what I want. Thanks to uncle Google.
Thanks all of you for your kind interest.
public dynamic GetValue(string name)
{
if (OpcDataList[name].IsChanged)
{
OpcReflectItem tmpItem = OpcDataList[name];
tmpItem.IsChanged = false;
OpcDataList[name] = tmpItem;
}
return Convert.ChangeType(OpcDataList[name].ItemValue.Value, OpcDataList[name].DataType);
}

C# private T CreateObject<T>()

i want to create an instance of object with a dynamic parameter like
private Type ClassType { get; set; }
model = (CreateObject<typeof(this.ClassType)>)ser.Deserialize(sr);
private T CreateObject<T>()
{
return (T)Activator.CreateInstance(this.ClassType);
}
i want to try it without a fix Type like "startconfig".
but it still doesnt work, can u help me?
var mi = GetType().GetMethod("CreateObject");
var miConstructed = mi.MakeGenericMethod(this.ClassType);
var instance = miConstructed.Invoke(this, null);
var model = (instance)ser.Deserialize(sr);
}
private T CreateObject<T>()
{
return (T)Activator.CreateInstance(this.ClassType);
}
this doesnt work anyway, cause: he type or namespace name 'type/namespace' could not be found (are you missing a using directive or an assembly reference?)
that happends at casting the ser.Deserialize(sr);
You wanna create an instance of T ? Then :
var model = CreateObject<StartConfig>();
private T CreateObject<T>()
{
return (T)Activator.CreateInstance(typeof(T));
}
with your second code sample, you might do something like that.
private Type ClassType { get; set; }
var mi = GetType().GetMethod("CreateObject");
var miConstructed = mi.MakeGenericMethod(ClassType);
var instance = miConstructed.Invoke(this, null);
model = (instance)ser.Deserialize(sr);
private T CreateObject<T>()
{
return (T)Activator.CreateInstance(typeof(T));
}
Try...
public class Factory<T>
{
public static T getInstance()
{
return getInstance(typeof(T), null);
}
public static T getInstance(object[] initializationParameters)
{
return (T)Activator.CreateInstance(typeof(T), initializationParameters);
}
{
What do you want to do with your model? I mean interface-wise. You have to define an interface which all Types adhere to that you deserialize.
public interface IModel
{
int ComputeFavoriteNumber(); // or a property
}
...
// class is practically unknown to deserializing module
internal class ErnieModel : IModel
{
public int ComputeFavoriteNumber()
{
return 8243721;
}
}
...
// deserializing module
var bf = new BinaryFormatter();
using (var ms = new MemoryStream())
{
bf.Serialize(ms, new ErnieModel()); // In reality ErnieModel should be unknown to the deserializing code, this is just to fill the Stream with data
ms.Position = 0;
var model = (IModel)bf.Deserialize(sr);
Console.WriteLine("Favorite number: {0}", model.ComputeFavoriteNumber());
}
You don't even need Activator.CreateInstance in this case. You do need it however, if you just saved the fully qualified name of the type or the type itself (not sure if that works) you want to create.
// interfaces/classes the same as above
Type deserializedType = typeof(ErnieModel); // or get it from wherever, maybe through (Type)bf.Deserialize(stream); ? In reality ErnieModel should be unknown to the deserializing code
var model = (IModel)Activator.CreateInstance(deserializedType);
Console.WriteLine("Favorite number: {0}", model.ComputeFavoriteNumber());
Using generics doesn't make sense in this case (though it feels like a good place to apply at first), you have to go with oldschool object and casting to a known interface type to enable true plugin-like extensions.

Categories