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;
}
}
}
}
Related
I know similar questions have been asked before, but I've come to a dead end while trying to find the best design pattern I can use.
I am trying to make a class-library with a factory class that provides enumerators for different items via method calls.
Note: Those items don't exist in a collection and can only be created knowing the previous one. (e.g. x(i) = x(i-1) + θ) Because of that I cannot implement those items as IEnumerable(s)
What I thought until now:
public static class AllItems {
public sealed class ItemsEnumerator: IEnumerator<Item>{
//those classes have non-public constructors
.....
}
public static ItemsEnumerator GetItemsEnumerator() {
return new ItemsEnumerator();
}
public sealed class OtherItemsEnumerator:IEnumerator<OtherItem>{
....
}
public static ItemsEnumerator GetOtherItemsEnumerator() {
return new ItemsOtherEnumerator();
}
}
this way i could do :
foreach(var item in AllItems.GetItemsEnumerator()){
//do something with item
}
which won't work, because according to c# spec ItemsEnumerator doesn't have a GetEnumerator function(To be used in a foreach statement)
If I change it to this
public static class AllItems {
public sealed class ItemsEnumerator: IEnumerator{
.....
public IEnumerator<Item> GetEnumerator() {
return this;
}
}
public static ItemsEnumerator GetItemsEnumerator() {
return new ItemsEnumerator();
}
}
Is this a good design in general, or am I missing something here?
EDIT: Clarification on c# spec limitation
I am trying to make a class-library with a factory class that provides enumerators for different items via method calls. Note: Those items don't exist in a collection and can only be created knowing the previous one. (e.g. x(i) = x(i-1) + θ) Because of that I cannot implement those items as IEnumerable(s)
You don't need to go to that level of detail - you can just use yield to achieve a "conceptual" collection without having to wire in all of the enumeration plumbing:
public IEnumerable<Item> GetItems()
{
int i = 0;
while(i < 100) // or foreach(Item item in _baseItems), etc.
{
Item item = new Item();
item.X = i;
i += 10;
yield return item;
}
}
Note that this is just for illustration to show one way of returning a "collection" of items that are generated on-the fly. You are free to adapt this to your situation in whatever way is appropriate.
Is there a faster way to clone the items than what is shown below?
private List<T> CloneItems(List<T> itemsToClone) {
lock (dataLocker) {
Stopwatch sw = Stopwatch.StartNew();
int numItems = itemsToClone.Count;
List<T> itemsToBeReturned = new List<T>(numItems);
for (int i = 0; i < numItems; i++) {
itemsToBeReturned.Add((T)itemsToClone[i].Clone());
}
Debug.WriteLine("CloneItems(ms): " + sw.Elapsed.TotalMilliseconds.ToString("F3"));
return itemsToBeReturned;
}
}
EDIT: I need a deep copy and am currently using it with the following object:
public class TimestampedDouble {
public long Timestamp { get; set; }
public double Voltage { get; set; }
public double Current { get; set; }
...
public override object Clone() {
return MemberwiseClone();
}
}
Like others have mentioned, you need to find the actual bottleneck. Your code above is fairly tight in terms of what it does. Likely, it's the clone and not your loop. However, it turns out that Microsoft already did that loop for you in the ConvertAll method and you could reimplement your code above like this:
var finallist = itemsToClone.ConvertAll<T>(o => (T)o.Clone());
However, I'm going to guess that it won't be a win since if I had been asked to implement ConvertAll, I would have done something close to your loop. And in fact, that's pretty much what MS did.
And that would point right back to your Clone method as the culprit.
You can use an Extension method like this:
static class Extensions
{
public static IList<T> Clone<T>(this IList<T> listToClone) where T: ICloneable
{
return listToClone.Select(item => (T)item.Clone()).ToList();
}
}
Looks pretty solid to me. Other suggestions would be less code, but not faster. Especially the suggestions when the array size is not pre-allocated.
Best idea I have is making TimestampedDouble a struct will be faster to get rid of the allocations and garbage collections.
But if you can restructure the rest of the code to not need entire lists, and pipeline instead, would be the best bet.
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.
I'm trying to create a wrapper around List to do some specific things I want, such as compute max min, extract specific values from some elements, etc.
I start with
public struct datum {
public UInt32[] chan;
public UInt64 sample_number;
public UInt32 time;
public UInt32 source_sector;
}
public class dataSet : List<datum> {
bool dirty=true;
....
}
the methods are typically like this (I want to know if the list has been modified as I have a max()/min() function that only parses the data when it has been modified and caches the values to reuse if the List has not been modified)
public new void Add(datum x ) {
base.Add(x);
this.dirty = true;
}
However, I'm not sure how to create a constructor. This syntax does not work.. how can I get this type of behavior?
public dataSet(int count) {
this = (dataSet) new List<datum>(count);
}
I also have this constructor, which seems to work fine (no compilation errors) though untested
public dataSet(List<datum> data) {
this.AddRange(data);
}
I came across a post that said that you should use a Collection and a List is used for speed. Though I need the speed, and I'm not sure why a Collection would be better?
--UPDATE--
I don't want to use linq as you can't create something that computes max/min simultaneously as efficiently as this:
public void recalculateMaxMin() {
foreach (var d in data) {
for (int i = 0; i < 16; i++) {
if (d.chan[i] > max[i]) max[i] = d.chan[i];
if (d.chan[i] < min[i]) min[i] = d.chan[i];
}
}
}
Thnx
I'm trying to create a wrapper around List to do some specific things I want, such as compute max min, extract specific values from some elements, etc.
Don't. Just use LINQ to Objects. That's what it was designed for:
var list = new List<int> { 10, 20, 30 };
var average = list.Average();
var max = list.Max();
// etc
In general, I would advise against deriving from List<T> anyway - that's not what it was designed for. However, if you must, you just chain from one constructor to a base constructor:
public dataSet(int count) : base(count)
{
// Add in any extra code you want to here. Probably none in this case.
// It would execute *after* the base constructor call.
}
See my article on constructors for more information about constructor chaining.
(I'd also strongly advise you to change the name - dataSet doesn't comply with .NET naming conventions, and DataSet would mean something else entirely to most .NET developers.)
You can never ever set "this" to something in C#. I think you are looking for this:
public dataSet(int count)
: base(count)
{ }
However in my opinion you should take a look at "System.Linq" namespace. I think what you are trying to implement has been done before by Microsoft. 'Select', 'Join', 'Where' and many other clauses has been already implemented in Linq. Also you can use "INotifyCollectionChanged" interface to implement the dirty thing.
Here are some references:
INotifyCollectionChanged
Linq
If you realy need to implement a complete List class with a new behavior, implementing "System.Collections.Generic.IList" interface is the only thing that will rock your idea in an advanced and perfect way. It's more customizable than inheriting from the List class and trying to change everything you have no access to.
Hope it helps
Cheers
public dataSet(int count)
: base(count) {
}
You can call the base type's constructor using base()
public dataSet(int count) : base(count)
{
// no need to implement anything here. base(count) will call the base
// type's constructor
}
I'm looking to add a "recently opened" functionality to my application, and was wondering if there was a simple built in way to do lists that "overflow". By this I mean, when you add an element beyond the capacity of the list, all the items are shifted.
Code example of desired functionality (obviously its not true, the list would actually contain A,B,C):
List<string> list = new List<string>();
//if Overflow was 2
list.Add("A");
list.Add("B");
//List now contains A,B
list.Add("C");
//List now contains B,C
Sorry for the simple question. The problem itself is obvious to solve (intail plan was to inherit from List), I just don't like having to re-invent the wheel and confuse future programmers with custom objects when the language or framework has that functionality.
As far as I know ther is no such collection in the library.
You can write this very easily, based on a List<> or an array.
// untested
class OverFlowList<T>
{
T[] _data;
int _next = 0;
public OferflowList(int limit)
{
_data = new T[limit];
}
void Add(T item)
{
_data[_next] = item;
_next = (_next + 1) % _data.Length;
}
}
You can do this easily with LinkedList<T>:
LinkedList<string> list = new LinkedList<string>();
//if Overflow was 2
list.AddFirst("A");
list.AddFirst("B");
list.AddFirst("C");
list.RemoveLast();
I would, personally, wrap this into a class that you could use, ie:
public class OverflowCollection<T> : IEnumerable<T>
{
private int max;
private LinkedList<T> list = new LinkedList<T>();
public OverflowCollection(int maxItems)
{
this.max = maxItems;
}
public void Add(T item)
{
this.list.AddFirst(item);
if (this.list.Count > max)
this.list.RemoveLast();
}
// Implement IEnumerable<T> by returning list's enumerator...
}
This provides a very simple method, which has some nice advantages, including being able to change the overload amount at runtime, etc..
Use a custom class that implement IList then when implement Add method check your constraint and do it.