How to output the members of list items? - c#

I'm a newbie in the C# and .NET at all.
So, I have a collection that contains objects
private List<object> trains = new List<object>();
...
trains.Add(trains[0]);
trains.Add(trains[1]);
trains.Add(trains[2]);
trains.Add(trains[3]);
trains.Add(trains[4]);
And later in my code I must to input all elements of my collection
I'm trying something like that, but it doesn't work
public void Display()
{
...
for (int i = 0; i<trains.Count; i++)
{
Console.WriteLine(trains[i].Number);
Console.WriteLine(trains[i].Destination);
}
}
Help me please, I'm really dont understand how to input it to the console. I read Microsoft documentation about the "List" but :(

You have a list of objects. And object class doesn't have those members (Number and Destination). If you wanna access them either you need to cast your objects to your type or have a list of Train instead of object.

Currently you are storing your objects in a List<object>, Since your class (probably named) Train inherit from Object, you can store its object in object. You need List<Train> and then you can access each member property like:
private List<Train> trains = new List<Train>();
If you can do that for some reason then you have to explicitly cast your object to Train like:
Console.WriteLine(((Train)(trains[i])).Number);

Assuming this
class Train
{
public int Number { get; set; }
public string Destination { get; set; }
}
And that you are doing something like this:
var t1 = new Train();
t1.Number = 1;
t1.Destination = "somewhere";
var t2 = new Train();
t2.Number = 2;
t2.Destination = "somewhereelse";
trains.Add(t1);
trains.Add(t2);
Than you can output using this:
Train train;
foreach(object t in trains)
{
if ((train = t as Train) != null)
{
Console.WriteLine(t.Number);
Console.WriteLine(t.Destination);
}
}
The advantage of using a list of objects is that you can put "anything" there. Not only "Train". But as pointed by #Chris, foreach do not filter, so you have to filter it yourself.

To access the Train object directly, you will need to cast the generic object to a Train object prior to referencing it's exposed properties. This can be done on the fly, it's not necessary to declare the extra variable myTrain here, however for sake of clarity and readability, I generally do it like this.
public void Display()
{
...
for (int i = 0; i<trains.Count; i++)
{
Train myTrain = (Train)trains[i];
Console.WriteLine(myTrain.Number);
Console.WriteLine(myTrain.Destination);
}
}
Others have mentioned and I would agree, I can think of very few situations where you would NEED to use a:
List<object>();
rather than:
List<Train>();
The only thing that jumps out at me would be if you might be storing non Train objects in the same list with Train objects but I cannot think of a good reason to do something like that off the top of my head.

Related

C# copying instance and modify new, while the previous is unchanged

I have such a problem with creating a new instances of object based on the existing instances.
To explain better what I want to do - imagine
I have one instance which I am passing to function and I want to copy the content of this existing instance to another instance and add something more to this new instance (but what is important that the first instance is not going to be changed at all).
So the first instance is 'freezed' and the new one is cloned and modified.
What I have done is the model:
public class Scenario
{
public List<SingleMove> listOfMoves { get; set; }
public List<int> listOfScores { get; set; }
public int totalScore { get; set; }
public Scenario(Scenario currentScenario)
{
listOfMoves = currentScenario.listOfMoves;
listOfScores = currentScenario.listOfScores;
totalScore = currentScenario.totalScore;
}
...
and now the function which is working on such objects
static public void ActivitiesForMoveWhites(Scenario currentScenario, int positionTo, int positionFrom)
{
Scenario singleScenario = new Scenario(currentScenario);
SingleMove singleMove = new SingleMove();
singleMove.checker = Configuration.chessfield[positionFrom];
singleMove.positionFrom = Logic.TranslateNumberOfFieldToString(positionFrom); //tutaj moze przechowywac to jako position czyli w intcie ?
singleMove.positionTo = Logic.TranslateNumberOfFieldToString(positionTo); //tutaj moze przechowywac to jako position czyli w intcie ?
singleScenario.listOfMoves.Add(singleMove);
Configuration.listOfScenarios.Add(singleScenario);
//Configuration.listOfScenarios.Add(new Scenario(singleScenario));
...
The problem is that all the different scenarios have the same listOfMoves. But it should be not like this. The current scenario should have copy the previous scenario content, add something, and the scenario that the content was copied from should stay at it was. So finally I have scenarios with different listOfMoves, not same !
Sorry for bit chaotic explanation. Please ask if you have questions or you need more details.
EDIT:
There was one more question but I solved it.
You must also clone the lists in your Scenario because = doesn't create a new instance of the list.
Try something like this in your constructor:
listOfMoves = new List<SingleMove>(currentScenario.listOfMoves.Select(x => (SingleMove)x.Clone()));
Edit:
You must implement IClonable in your SingleMove Object

C# Dynamic extends a object

is it possible to extends a existing object ?
i have the code
var record = new
{
id,
name
};
and have a list of anonymous objects
var list = new List<object>(){ object1, object2 };
Can i add them later to the object ?
Like something as
foreach (var o in list)
{
record.add(o);
}
that i will get this as result
var record = new
{
id,
name,
object1,
object2
};
In short, no. At least, not with anonymous types. There are two approaches here; dynamic might give you what you want, but is fiddly for combining. Other than that, a basic property bag - even simply Dictionary<string,object> would do. The only difference being that:
obj.id
becomes
obj["id"]
There is a more fundamental problem, though, in trying to combine a list (each of which is largely anonymous) with properties in a single step. You can do this for data-binding purpose via custom property models, but it is... tricky.
What you can do is create a class Extension. It is not possible to add new methods in the runtime, but you can do something like this:
public class OneClass
{
private List<object> items;
public List<object> Items { get { return items; } }
public void AddOne(object item)
{
items.Add(item);
}
}
if you want to extend this class behavior, you can write an extension class. Like this:
public static class OneClassExtensions
{
public void AddMany(this OneClass self, params object[] items)
{
foreach(object item in items)
{
self.Items.Add(item);
}
}
}
This way you can call this extension method from your OneClass objects:
OneClass obj = new OneClass();
obj.AddOne("hello");
obj.AddMany("Hello", "world"); // Extension method
There are some rules to follow:
The extension class must have the `static' modifier
you need to put the `this' prefix before the first argument. This argument would be the object itself.
In order to use this extension class in your code, you must use the namespace that contains that extension class, like `using Some.Namespace.That.Has.An.Extension' in every .cs file where you want to use extension methods.
In case anyone runs into this question in the future, I have recently published a library to do exactly this. You can find it on nuget.org - it's called (unsurprisingly) ObjectExtend.
You can install it by grabbing it from Nuget or via your favourite package manager. You can also check out the source code, a brief introduction, or a detailed overview of how it works.
The short version is - install the package, make sure you import the namespace with using Rophuine.LINQPad.ObjectExtend;, and now you should be able to call .Extend on your objects.
A caveat: this is a great technique for exploratory coding, but I recommend against it for anything which will be maintained or go to production.
Since .net4 you could use ExpandoObject to do stuff like that.
For example:
var objs = new List<ExpandoObject>();
for (var i = 0; i < 10; i++)
{
dynamic eObj = new ExpandoObject();
eObj.Property = i;
objs.Add(eObj);
}
foreach (dynamic obj in objs)
{
obj.Property2 = "bubuValue" + obj.Property;
obj.Property3 = "bubuValue" + obj.Property2;
}
foreach (dynamic obj in objs)
{
Console.WriteLine(obj.Property3);
}

help with c# array

I have a datatable with two columns. I want to store the rows of each column in an array so that I can return rows for each individual column. This way I believe I can populate a list box(the option text as one column and the option value as the other column).
Here is what I started out with:
public object dbAccess2()
{
ArrayList arg = new ArrayList();
DataTable myTable = GenericDataAccess.ExecuteSelectCmd("Vehicle_GetMakes");
foreach (DataRow dRow in myTable.Rows)
{
arg.Add(dRow["VehicleMake"]);
arg.Add(dRow["VehicleMakeId"]);
}
return arg.ToArray();
}
You can make a class to hold each individual row in this case and use a List<T> to hold the data, like this:
public class Vehicle
{
public string Make { get, set };
public string MakeId { get, set };
}
..
List<Vehicle> Vehicles = new List<Vehicle>();
..
foreach (DataRow dRow in myTable.Rows)
{
Vehicles.Add(
new Vehicle {
Make = arg.Add(dRow["VehicleMake"]),
MakeId = arg.Add(dRow["VehicleMakeId"])
});
}
And later, you can easily populate a listbox with this list:
listBox.DataSource = Vehicles;
listBox.DisplayMember = "Make";
But I think you may want to use a ListView probably.
Don't use the ArrayList class, it's practically obsolete. Use arrays or generic lists instead, so that you get a typed result.
You can get the columns into lists like this:
List<string> makes = myTable.Rows.Select(r => (string)r["VehicleMake"]).ToList();
List<int> makeIds = myTable.Rows.Select(r => (int)r["VehicleMakeId"]).ToList();
Or into arrays:
string[] makes = myTable.Rows.Select(r => (string)r["VehicleMake"]).ToArray();
int[] makeIds = myTable.Rows.Select(r => (int)r["VehicleMakeId"]).ToArray();
An alternative to populating a dropdown (as that is what I assume that you mean, as a ListBox doesn't have options) from arrays is to use data binding:
theDropdown.DataTextField = "VehicleMake";
theDropdown.DataValueField = "VehicleMakeId";
theDropdown.DataSource = myTable;
theDropdown.DataBind();
What you're attempting is to manipulate real objects without the benefit of object design, invoking raw data instead. This has very broad and far-reaching problems and is quite far behind current development strategies - to broad to go into here but not least of your problems is building in a brittle coupling between your application and your database.
Step one is to model an actual Vehicle class.
public class Vehicle
{
public string MakeId { get; set; }
public string Make { get; set; }
}
Step two is to build a managing class for your Vehicles ("Fleet" perhaps?) which can abstract the Vehicle collection behind an IEnumerable interface. Internally you will store the Vehicles collection as a concrete generic collection (a List or Dictionary most likely) and avoid at all costs the really-should-be-considered-obsolete ArrayList structure.
public class Fleet
{
private List<Vehicle> _vehicles = new List<Vehicle>();
public IEnumerable<Vehicle> Vehicles { return this._vehicles;}
}
Step three is to internalise to this class (or a class behind this one or behind that one etc, etc) the CRUD operations which will interact with the Database stored data. That's truly an implementation detail, but one you'll apply for all similar classes throughout your architecture.
At this point you'll be able to work with the IEnumerable property directly with standard Databinding methods.

Anonymous classes, temporary data, and collections of anonymous classes

I'm new to anonymous classes, and today I think I ran into the first case where I felt like I could really use them. I'm writing a method that would benefit from storing temporary data inside of a class, and since that class doesn't have any meaning outside of that method, using an anonymous class sure made sense to me (at least at the time it did).
After starting on the coding, it sure seemed like I was going to have to make some concessions. I like to put assign things like calculations to temporary variables, so that during debugging I can verify bits of calculations at a time in logical chunks. Then I want to assign something simpler to the final value. This value would be in the anonymous class.
The problem is that in order to implement my code with anonymous classes concisely, I'd like to use LINQ. The problem here is that I don't think you can do such temporary calculations inside of the statement. or can you?
Here is a contrived example of what I want to do:
namespace AnonymousClassTest
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
ObservableCollection<RectanglePoints> Points { get; set; }
public class RectanglePoints
{
public Point UL { get; set; }
public Point UR { get; set; }
public Point LL { get; set; }
public Point LR { get; set; }
}
public class DontWantThis
{
public double Width { get; set; }
public double Height { get; set; }
}
private Dictionary<string,string> properties = new Dictionary<string,string>();
private Dictionary<string,double> scaling_factors = new Dictionary<string,double>();
private void Sample()
{
// not possible to do temp variables, so need to have
// longer, more unreadable assignments
var widths_and_heights = from rp in Points
select new
{
Width = (rp.UR.X - rp.UL.X) * scaling_factors[properties["dummy"]],
Height = (rp.LL.Y - rp.UL.Y) * scaling_factors[properties["yummy"]]
};
// or do it in a for loop -- but then you have to use a concrete
// class to deal with the Width and Height storage
List<DontWantThis> other_widths_and_heights = new List<DontWantThis>();
foreach( RectanglePoints rp in Points) {
double base_width = rp.UR.X - rp.UL.X;
double width_scaling_factor = scaling_factors[properties["dummy"]];
double base_height = rp.LL.Y - rp.UL.Y;
double height_scaling_factor = scaling_factors[properties["yummy"]];
other_widths_and_heights.Add( new DontWantThis
{
Width=base_width * width_scaling_factor,
Height=base_height * height_scaling_factor
});
}
// now we want to use the anonymous class, or concrete class, in the same function
foreach( var wah in widths_and_heights)
Console.WriteLine( String.Format( "{0} {1}", wah.Width, wah.Height));
foreach( DontWantThis dwt in other_widths_and_heights)
Console.WriteLine( String.Format( "{0} {1}", dwt.Width, dwt.Height));
}
public Window1()
{
InitializeComponent();
Points = new ObservableCollection<RectanglePoints>();
Random rand = new Random();
for( int i=0; i<10; i++) {
Points.Add( new RectanglePoints { UL=new Point { X=rand.Next(), Y=rand.Next() },
UR=new Point { X=rand.Next(), Y=rand.Next() },
LL=new Point { X=rand.Next(), Y=rand.Next() },
LR=new Point { X=rand.Next(), Y=rand.Next() }
} );
}
Sample();
}
}
}
NOTE: don't try to run this unless you actually add the keys to the Dictionary :)
The creation of the anonymous class in LINQ is awesome, but forces me to do the calculation in one line. Imagine that the calc is way longer than what I've shown. But it is similar in that I will do some Dictionary lookups to get specific values. Debugging could be painful.
The usage of a concrete class gets around this problem of using temporary variables, but then I can't do everything concisely. Yes, I realize that I'm being a little contradictory in saying that I'm looking for conciseness, while asking to be able to save temp variables in my LINQ statement.
I was starting to try to create an anonymous class when looping over Points, but soon realized that I had no way to store it! You can't use a List because that just loses the entire anonymity of the class.
Can anyone suggest a way to achieve what I'm looking for? Or some middle ground? I've read a few other questions here on StackOverflow, but none of them are exactly the same as mine.
Assuming I understand you correctly, the problem is that you have to set all the properties in a single expression. That's definitely the case with anonymous types.
However, you don't have to do it all inline in that expression. I would suggest that if your properties are based on complex expressions, you break those expressions out into helper methods:
var complex = new {
First = ComputeFirstValue(x, y),
Second = ComputeSecondValue(a, b)
...
};
This has the additional potential benefit that you can unit test each of the helper methods individually, if you're a fan of white-box testing (I am).
This isn't going to avoid there being in one big anonymous type initializer expression, but it means the work will be broken up.
Anonymous classes are really intended to simplify stuff dealing with lambdas, not least LINQ. What you're trying to do sounds much more suited to a nested private class. That way, only your class really knows about your temp class. Trying to muck around with anonymous classes seems only to complicate your code.

Generic Linked List

Before posting my question, I would like to tell you that I have no prior experience in .Net technologies and have recently started to learn C# (and WPF). My company is looking to move onto .Net technologies and I am the only one in my team learning it, so have noone apart from you guys to discuss or ask something. So if my questions are too stupid or basic at best, please bear with me.
I was trying to create a generic linked list class to allow creation of linked lists of different types. I wrote the following code and would like to have your advise on whether I have written this code properly or not. Any suggestions to improve the code in any way is most welcome.
Main program
class Program
{
static void Main(string[] args)
{
GenLinkedList<string> list = new GenLinkedList<string>("abc");
list.AddtoList("def");
int i = 0;
string[] arr = new string[10];
list.LinkedList.CopyTo(arr,0);
for (i = 0; i < list.LinkedList.Count; i++)
{
Console.WriteLine(arr[i]);
}
GenLinkedList<int> listInt = new GenLinkedList<int>(1);
listInt.AddtoList(2);
i = 0;
int[] arrInt = new int[10];
listInt.LinkedList.CopyTo(arrInt, 0);
for (i = 0; i < listInt.LinkedList.Count; i++)
{
Console.WriteLine(arrInt[i]);
}
}
}
Class GenLinkedList
public class GenLinkedList<T>
{
private LinkedList<T> _linkedlist;
public GenLinkedList(T a)
{
_linkedlist = new LinkedList<T>();
_linkedlist.AddLast(a);
}
public LinkedList<T> LinkedList
{
get
{
return _linkedlist;
}
}
public void AddtoList(T a)
{
LinkedList.AddLast(a);
}
}
Why not use System.Collections.Generic.LinkedList<T>? You're using it internally in your GenLinkedList<T> already and it's already Generic for you.
It's the Framework Provided Generic Doubly Linked List implementation. Read up on it at:
MSDN - LinkedList(T) Class
If you're creating a Generic Linked List as an exercise, you shouldn't base your implementation of of an existing Generic Linked List. You're really not going to be learning anything by wrapping something that already does exactly what you need to do.
1
A generic linked list implementation already exists in the .NET framework: LinkedList<T>. But you already know that; your code wraps it.
2
OK, so you know that. Why would you wrap it, then? The only functionality you appear to have implemented is AddtoList, which doesn't do anything the LinkedList<T> doesn't already do itself (after all, this is only a thin wrapper around LinkedList<T>.AddLast). What this means is that your GenLinkedList<T> class really doesn't offer the functionality of a linked list; it's basically an add-only collection (which could just as easily have been implemented with a List<T>, or a Stack<T>, or a Queue<T> -- anything, really).
3
Assuming you do have a good reason to wrap a LinkedList<T> (e.g., you're planning to add more functionality down the line that would actually leverage the behavior of a LinkedList<T> and/or -- here's a key ingredient -- you want to restrict the way calling code is able to interact with the list (e.g., no removals)), you really shouldn't expose your LinkedList<T> member at all. The purpose of a wrapper is just that: to wrap. You take an existing class and basically give it a new kind of interface. By exposing the underlying object directly, you cripple your wrapper. Any additional restrictions/validation/logic you have in your wrapper can be bypassed.
So, for example, if you want to be able to copy your list to an array, instead of doing this:
list.LinkedList.CopyTo(arr,0);
You would implement a CopyTo method within your GenLinkedList<T> class (which could simply call _linkedlist.CopyTo) and use that.
But I really think the first question you should be asking yourself is what you want to accomplish by wrapping LinkedList<T> in the first place.
The obvious question is why you don't just use LinkedList<T> directly, although it looks like you're trying to emulate a singly-linked list.
In this case, you should avoid exposing the underlying LinkedList<T> instance, since any client could manipulate it directly. I would also implement IEnumerable<T> which will make your list usable by linq.
I got this from http://msdn.microsoft.com/en-us/library/0x6a29h6.aspx
Works fine with me.
namespace GenLinkedList
{
class Program
{
static void Main(string[] args)
{
GenericList<object> list = new GenericList<object>();
// Add items to list.
list.AddHead("some string here");
list.AddHead(DateTime.Today.ToLongDateString());
list.AddHead(13);
list.AddHead(13.005);
for (int x = 0; x < 10; x++)
{
list.AddHead(x);
}
// Enumerate list.
foreach (object i in list)
{
Console.WriteLine(i + " " + i.GetType());
}
Console.WriteLine("\nDone");
}
}
}
namespace GenLinkedList
{
// type parameter T in angle brackets
class GenericList<T>
{
// The nested class is also generic on T.
public class Node
{
private Node next;
// T as private member data type.
private T data;
// T used in non-generic constructor.
public Node(T t)
{
next = null;
data = t;
}
public Node Next
{
get { return next; }
set { next = value; }
}
public T Data
{
get { return data; }
set { data = value; }
}
}
private Node head;
// constructor
public GenericList()
{
head = null;
}
// T as method parameter type
public void AddHead(T t)
{
Node n = new Node(t);
n.Next = head;
head = n;
}
public IEnumerator<T> GetEnumerator()
{
Node current = head;
while (current != null)
{
yield return current.Data;
current = current.Next;
}
}
}
}

Categories