How to determine array in class? - c#

I have a class like this:
class Zmogus
{
public string Vardas { get; set; }
public int Draugu_Kiekis { get; set; }
public string[] Draugas { get; set; }
public Zmogus(string vardas, int draugu_Kiekis, string[] draugas)
{
Vardas = vardas;
Draugu_Kiekis = draugu_Kiekis;
Draugas = draugas;
}
public Zmogus()
{
}
}
And i would like to know how to determine the size of it, because when i use it like this:
zmogus.Draugas[i] = parts[i+2];
It just shows me that the "Draugai" parameter is null.

Add the property:
public int DraugasLength{get {return this.Draugas.Length} set;}
or just use Draugas.Length. I think that behavior you are looking for is more like list than array - I would recommend using List from System.Collections.Generic instead of arrays.

Related

dynamic to specific class object conversion

how to convert dynamic variable to specific class.
dynamic variable has the same properties as my specific class.
public class PracovnikHmotZodpovednostDropDownListItem
{
[Column("ZAZNAM_ID")]
public int? ZaznamId { get; set; }
[Column("TEXT")]
public string Text { get; set; }
[Column("VALL")]
public int Value { get; set; }
public bool Disabled { get; set; } = false;
public UpdateStatusEnum UpdateStatus { get; set; }
}
void someMethod(dynamic dtos){
List<PracovnikHmotZodpovednostDropDownListItem> dto =
(List<PracovnikHmotZodpovednostDropDownListItem>)dtos;
}
If all you know is that the properties have the same names, you're in duck typing territory, casting won't help you.
Good news is, it's trivial to do, just tedious:
var dtoList = new List<PracovnikHmotZodpovednostDropDownListItem>();
foreach(var dto in dtos)
dtoList.Add(new()
{
ZaznamId = dto.ZaznamId,
Text = dto.Text,
// etc..
});

C# List of generic class/type as a property or memeber of a class

I am not sure how to create a List that holds elements of a generic data type using C#.
Currently I have two very similar classes defined in my code:
public class ClassOne
{
public int draw { get; set; }
public int recordsTotal { get; set; }
public int recordsFiltered { get; set; }
public List<SpecialClass> data { get; set; }
}
public class ClassTwo
{
public int draw { get; set; }
public int recordsTotal { get; set; }
public int recordsFiltered { get; set; }
public List<YTDTRNSLine> data { get; set; }
}
My current thought process was that I should generalize these two classes into one class. Since the only difference is one of the properties which is a List.
Do I define the List with something like this:
public List<object> data {get;set;}
?
When I tried to use List<object>, I tried to do something like this:
ClassOne classOneObj = new ClassOne();
classOneObj.data = myFunctionHere();
Where myFunctionHere() returns a List of a datatype/class which I have defined on my own. When I do this, there will this error message shown:
Cannot implicitly convert type List<MyOtherClass> to List<object>.
I am stuck as of now. How do I go about create a list of a generic type? Thank you in advance!
If the classes are so similar, I would join them entirely. There is a problem though with the different types on the data classes, but you can solve that with generics:
public class ClassOne<T>
{
public int draw { get; set; }
public int recordsTotal { get; set; }
public int recordsFiltered { get; set; }
public List<T> data { get; set; }
}
Then define the variables as:
ClassOne<SpecialClass> classOneObj = new ClassOne<SpecialClass>();
ClassOne<YTDTRNSLine> classTwoObj = new ClassOne<YTDTRNSLine>();

Is there a shortcut to convert a model to a view model?

I am new to c# and .NET. I am learning ASP.NET MVC 5. One thing that I am finding myself spending extra time doing in converting a model to a viewmodel.
Here is my model
public class Overview
{
public string chain_name { get; set; }
public int store_id { get; set; }
public int total_attempts { get; set; }
public int total_unique_number_called { get; set; }
public int total_callable { get; set; }
public int total_completed_interviews { get; set; }
}
and here is my view model
public class OverviewViewModel
{
public string chain_name { get; set; }
public int store_id { get; set; }
public int total_attempts { get; set; }
public int total_unique_number_called { get; set; }
public int total_callable { get; set; }
public int total_completed_interviews { get; set; }
public decimal? unique_number_per_complete { get; set; }
public OverviewViewModel()
{
unique_number_per_complete = 0;
}
}
as you can see both Model and ViewModel are identical except for over variable which is a calculation.
To populate my view model I do the following
var records = conn.Database.SqlQuery<Overview>(query).ToList();
var overView = new List<OverviewViewModel>();
foreach(var record in records){
var newRecord = new OverviewViewModel();
newRecord.store_id = record.store_id;
newRecord.chain_name = record.chain_name;
newRecord.total_attempts = record.total_attempts;
newRecord.total_callable = record.total_callable;
newRecord.total_completed_interviews = record.total_completed_interviews;
if (record.total_completed_interviews > 0) {
newRecord.total_unique_number_called = record.total_unique_number_called / record.total_completed_interviews;
}
overView.Add(newRecord);
}
The two issues that I am seeing with my approach is that
I have to do lots of extra coding especially of the view model is large or f I have multiple variables that I need to calculate.
I feel I am looping 1 extra time to convert my model to view mode.
Is there an easier way to do this in c#?
Is there a better approach with this procedure for a large application? My goal is to learn the better way to utilize my code time to the fullest.
I agree that you should look into automapper, but another way would be to create a constructor on your OverviewViewModel model that takes and Overview object and populates all the properties. Something like
public class OverviewViewModel {
public string chain_name { get; set; }
public int store_id { get; set; }
public int total_attempts { get; set; }
public int total_unique_number_called { get; set; }
public int total_callable { get; set; }
public int total_completed_interviews { get; set; }
public decimal? unique_number_per_complete { get; set; }
public OverviewViewModel()
{
unique_number_per_complete = 0;
}
public OverviewViewModel(Overview record)
{
store_id = record.store_id;
chain_name = record.chain_name;
total_attempts = record.total_attempts;
total_callable = record.total_callable;
//etc
}
}
Then your code would look like
var overView = new List<OverviewViewModel>();
foreach(var record in records){
overView.Add(new OverViewViewModel(record));
}
Yes, you should use Automapper, install package view Nuget. Automapper is very configurable as well.
http://automapper.org/
First, create this class:
public static class AutoMapperConfig
{
public static void RegisterMappings()
{
//Example here, creates "two way" for Overview & OverviewViewModel mapping
Mapper.CreateMap<Overview, OverviewViewModel>(); //<source, destination>
Mapper.CreateMap<OverviewViewModel, Overview>(); //<source, destination>
//..more mapping for other Models and ViewModels.
}
}
In Global.asax.ApplicationStart() add this line:
AutoMapperConfig.RegisterMappings()
Now your foreach example in your comments is nice and simple:
foreach (var record in records)
{
var newRecordOverviewViewModel = Mapper.Map<OverviewViewModel>(record); //<destination>(source)
overView.Add(newRecordOverviewViewModel);
}
Another alternative is to use Linq and extension methods as below
using System.Collections.Generic;
using System.Linq;
using App.Data.Entities;
using App.Business.Models;
namespace App.Business
{
public static partial class OverviewAdapter
{
public static OverviewViewModel ToOverviewViewModel(this Overview overview)
{
return new OverviewViewModel
{
chain_name = overview.chain_name,
store_id = overview.store_id,
total_attempts = overview.total_attempts,
total_unique_number_called = overview.total_unique_number_called,
total_callable = overview.total_callable,
total_completed_interviews = overview.total_completed_interviews,
unique_number_per_complete = 0
};
}
public static IEnumerable<OverviewViewModel> ToOverviewModelList(this IEnumerable<OverviewViewModel> overviewList)
{
return (overviewList != null) ? overviewList.Select(a => a.ToOverviewViewModel()) : new List<OverviewViewModel>();
}
// Reverse - ToOverview / ToOverviewList if needed...
}
}
Now, anytime your Business class is in scope, you have a discoverable method on the class and the list of class which can be added inline.
var records = conn.Database.SqlQuery<Overview>(query).ToOverviewModelList().ToList();
This more functional approach is intuitive, streamlined, and you have immediate feedback if an adapter has not yet been written.
It is a personal preference whether to return an IEnumerable or List from the list version. The broader IEnumerable is the more conventional solution, but I tend to be going from List<> to List<> all of the time and dropping down into IEnumerable seems superfluous.

class design: How do I create a class with nested objects?

I am currently developing a client library for connecting to Newegg using the documentation provided by Newegg and have a question on class design.
In working with various API's ( namely NetSuite and Amazon's MWS ) I come across classes that have are used like this:
recToFulfill.packageList = new ItemFulfillmentPackageList();
recToFulfill.packageList.package = new ItemFulfillmentPackage[ifitemlist.item.Length];
recToFulfill.packageList.package[i] = new ItemFulfillmentPackage();
recToFulfill.packageList.package[i].packageWeightSpecified = true;
recToFulfill.packageList.package[i].packageTrackingNumber = "trackingNumber";
The question I have is: How do I properly design the nested objects like above? I have never had to worry about this previously, so I am unsure on where to look, or start.
The bit I need to figure out looks like this ( taken from the API documentation provided):
<UpdateOrderStatusInfo>
<IsSuccess></IsSuccess>
<Result>
<OrderNumber></OrderNumber>
<SellerID></SellerID>
<OrderStatus></OrderStatus>
</Result>
</UpdateOrderStatusInfo>
All fields are type string, except order number which is an integer.
I have this currently:
public class UpdateOrderStatusInfo
{
public string IsSuccess { get; set; }
public int OrderNumber { get; set; }
public string SellerID { get; set; }
public string OrderStatus { get; set; }
}
But the returned XML Response has Results as a parent node which to me seems like it should be represented within the class itself. Would I just do this?
public UpdateOrderStatusInfo results {get; set;}
If so, where do the child nodes go?
What I need is to be able to say is something like:
UpdateOrderStatusInfo updateInfo = new UpdateOrderStatusInfo();
if(updateInfo.IsSuccess.Equals("true")
{
Console.WriteLine(updateInfo.Results.OrderStatus);
}
Any help, or advice on where to get this information is appreciated.
Easy breezy. If it has no children, it's a scalar property. If it does, it is its own class, and referenced in the parent class accordingly. If it repeats, it's a collection, and is referenced like a class (these are complex type, not primitives). Make sure you initialize them in your constructors).
class Program
{
static void Main(string[] args)
{
var myOrder = new UpdateOrderStatusInfo();
myOrder.IsSuccess = "true";
myOrder.OrderResult.OrderNumber = 1001;
myOrder.OrderResult.OrderStatus = "Pending";
myOrder.OrderResult.SellerID = "69";
}
}
public class UpdateOrderStatusInfo
{
public string IsSuccess { get; set; }
public Result OrderResult { get; set; }
public UpdateOrderStatusInfo()
{
OrderResult = new Result();
}
}
public class Result
{
public int OrderNumber { get; set; }
public string SellerID { get; set; }
public string OrderStatus { get; set; }
}
You need to define the Result as a separate class, called whatever you want, then add a Result property as that type. The Result class can be defined at the namespace level, or, if you are unlikely to use it anywhere else on its own, you can nest the class definition inside the UpdateOrderStatusInfo class:
public class UpdateOrderStatusInfo
{
public class UpdateOrderResult
{
public int OrderNumber { get; set; }
public string SellerID { get; set; }
public string OrderStatus { get; set; }
}
public UpdateOrderStatusInfo()
{
Result = new UpdateOrderResult();
}
public string IsSuccess { get; set; }
public UpdateOrderResult Result { get; set; }
}
The easy way is to use the xsd.exe tool.
The command xsd response.xml will generate the file response.xsd
The command xsd response.xsd /C will generate the file response.cs which contains the classes necessary to serialize/deserialize the xml posted.

Storing and retrieving from lists with custom structures in

I'm having some trouble storing and retrieving items into a list<> with a custom structure.
My structure looks like this:
public class list_rss_parameters
{
public string this_string { get; set; }
public string title_start { get; set; }
public string title_end { get; set; }
public string description_start { get; set; }
public string description_end { get; set; }
public string link_start { get; set; }
public string link_end { get; set; }
public string publish_date_start { get; set; }
public string publish_date_end { get; set; }
public string author_start { get; set; }
public string author_end { get; set; }
}
My stored procedure looks like this (and note that the variable names are the same as the custom Key names) Is this ok?
//this is the last part of a custom method that returns a list
List<list_rss_parameters> list_rss_items = new List<list_rss_parameters>();
list_rss_items.Add(new list_rss_parameters()
{
this_string = this_string,
title_start = title_start,
title_end = title_end,
description_start = description_start,
description_end = description_end,
link_start = link_start,
link_end = link_end,
publish_date_start = publish_date_start,
publish_date_end = publish_date_end,
author_start = author_start,
author_end = author_end
});
return list_rss_items;
If the above two setups are correct, how do I pull items out of the List once I return it?
List<list_rss_parameters> list_rss_parameters = new List<list_rss_parameters>();
list_rss_parameters = f_discover_rss_parameters(rss);
show(list_rss_parameters.Count.ToString());
show(list_rss_parameters[0].ToString()); //does not show this_string
show(list_rss_parameters[this_string'] //does not show this_string
show(list_rss_parameters[0][this_string'];//does not show this_string
What am I doing wrong?
You want the this_string property of the first item in your list it seems:
show(list_rss_parameters[0].this_string);
Or show all of them:
foreach(var item in list_rss_parameters)
{
Console.WriteLine(item.this_string);
}
As a side note your property names don't match the PascalCase naming convention for properties in .NET - so this_string really should be ThisString.

Categories