how can i convert a long variable into the list?
Code:
long taskId = long.Parse(LocalWorkListVM.ActiveTask.TaskId, CultureInfo.InvariantCulture);
I need to convert it into a List<long> because one of our method expect a list to pass.
So you need a List<long> but you only have a single variable. That's easy, you can use the collection initializer syntax:
List<long> longs = new List<long>{ taskId };
or more verbose with List.Add:
List<long> longs = new List<long>();
longs.Add( taskId );
Try this:
List<long> somelist = new List<long>{long.Parse(LocalWorkListVM.ActiveTask.TaskId, CultureInfo.InvariantCulture)};
This will create a new List and initialise it with the parsed value.
Does it really need to be a List? If there is a way to modify that method to accept an IEnumerable things would get much easier and cleaner (or if IEnumerable is not enough, maybe consider IList).
So considering this, you have a bunch of options.
You can use the Enumerable class' static method Repeat:
Enumerable.Repeat(taskId, 1);
You can write your own extension method:
static class IEnumerableExtensions
{
public static IEnumerable<T> ToEnumerable<T>(this T item)
{
yield return item;
}
}
// and use it as:
taskId.ToEnumerable()
Of course this extension method can be modified to return a List or IList or whatever your exact needs are.
Also, you might create a new overload of the function, which expects a single long instead of the List, somewhere along the lines of this:
public void MyMethod(List<long> list)
{
// Do something
}
public void MyMethod(long item)
{
MyMethod(new List<long>{ item });
}
And finally, there is a nice keyword called params:
public void MyMethod(params long[] items)
{
// call to the previously mentioned extension method
MyMethod(items.ToEnumerable());
}
public void MyMethod(IEnumerable<long> items)
{
// Do stuff
}
This solution has the advantage to work with a single long parameter, comma separated long parameters or with an IEnumerable<long>.
Related
Hi I'm learning Generics thru MSDN here
and I want to do a foreach loop to display data in a console.writeline.
I tried to do the foreach loop as below but it's not working.
// Declare the generic class.
public class GenericList<T>
{
public void Add(T input) { }
}
class TestGenericList
{
private class ExampleClass { }
static void Main()
{
// Declare a list of type int.
GenericList<int> list1 = new GenericList<int>();
list1.Add(150);
// Declare a list of type string.
GenericList<string> list2 = new GenericList<string>();
list2.Add("Toyota");
// Declare a list of type ExampleClass.
GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
list3.Add(new ExampleClass());
}
}
foreach (GenericList<T> item in list2.ToString().ToList())
{
Console.WriteLine(item); // NOT WORKING !!!!
}
Firstly, by calling the method ToString() on list2, you will get the name of type of your object, because you didn't create your own implementation of method ToString(). So, you are trying to enumerate through letters of string "AppName.GenericList". Unfortunately, letters are of type 'char' and not GenericList.
Secondly, there is no backend behind method Add - items you are 'adding' to your list, in reality aren't added anywhere. Method public void Add(T input) { } does nothing (you should fill the brackets). GenericList at this stage stores no data.
Thirdly, you can't enumerate through your GenericList, because you didn't implement the method GetEnumerator. Only then you will be able to use keyword foreach on objects of your type.
Many of this issues will be solved by the end of the tutorial from link that you provided.
Right now my code looks like this:
var ids = projectId.HasValue ? new List<Guid> { projectId.Value } : new List<Guid>();
Is there a more succinct way of creating a list in one line of code, with one element added optionally?
Another idea for an extension method (the name could definitely be improved, maybe PossiblyCreateSingletonList?):
public static class NullableExtensions
{
public static List<T> SingletonList<T>(this Nullable<T> item) where T : struct
{
return item.HasValue ? new List<T> { item.Value } : new List<T>();
}
}
Usage:
Guid? projectId = null;
List<Guid> projectIds = projectId.SingletonList(); // empty list
I would solve this using a extension method like this:
public static void AddIfNotNull<T>(this List<T> list, T? value) where T : struct
{
if(value != null)
{
list.Add(value.Value);
}
}
Than it could be used like this:
var ids = new List<Guid>();
ids.AddIfNotNull(projectId);
Maybe not as "crafty" (and not a one-liner) as your proposal, but in my opinion it is much easier to read and understand. If desired to be used as a one-liner you could modify the return type of the extension to be the list. That would make it possible to be used something like var ids = new List<Guid>().AddIfNotNull(projectId);
This probably isn't a good idea, but in C# 6, collection initializers also work when Add() is an extension method.
This means you can write the extension Add() like this:
public static void Add<T>(this List<T> list, T? item) where T : struct
{
if (item.HasValue)
{
list.Add(item.Value);
}
}
And then this code will do what you want:
var list = new List<Guid> { projectId };
Note that this will only work for value types (because of the T/T? distinction) and there is no simple way to make it work for reference types.
Also, I would find the line above very surprising, being more succinct is not always better. Which is why I actually wouldn't use this code.
That's pretty succinct, but another option would be to use LINQ:
var ids = new[] { projectId }.Where(x => x.HasValue).Select(x => x.Value).ToList();
If you're going the extension method route, it would have to look something like:
public static void AddIfNotNull<T>(this List<T> list, T? value)
where T : struct
{
if (value.HasValue)
{
list.Add(value.Value);
}
}
You'd have to build a second extension method for reference types (where T : class) if you needed.
Hi
i have created a Generic Array that works fine for Int,String, Float or even my Own type named Customers.
Generic Array has functions Add(), Sort(), ShowAll() thats working fine for Int, String, and even Customer Type
except when i try to showAll() method for CustomerType that shows all the values that i have added through ADD() method.
output is something like
GenericArray.Customer
not the values where as i wanted to have the values .
i have solved it through
public class GArray<T> where T : Customer
but now i cant create Generic Array of type Int,Float .
here is the ADD and ShowAll method of Class
public void Add(T temp)
{
if (index >= values.Length)
{
T[] tempArray = new T[values.Length + 1];
Array.Copy(values, tempArray, values.Length);
values = tempArray;
}
values[index] = temp;
index++;
}
public void ShowAll()
{
for (int i = 0; i < values.Length; i++)
{
Console.WriteLine(values[i]);
}
}
the values m adding
static void Main(string[] args)
{
GArray<Customer> customers = new GArray<Customer>(3);
customers.Add(new Customer(101, "xyz"));
customers.Add(new Customer(59, "abc"));
customers.ShowAll();
}
i have talked with my frnd and he said that i have to create indexer my self . can some one help me how can i create indexer in this case that works fine for customerType or any Type.
I think,If I understand the question (output is something like GenericArray.Customer, not the values where as i wanted to have the values) you should add in Customer definition:
public override string ToString()
{
// return something you want to show to identify your customer
// e.g. return Name;
return ...
}
I explain: when you use Console.WriteLine(values[i]) you tell C# to write to console Customer object... and it writes out then name of the class, as it's the default behaviour.
Defining in Customer class the default string to be converted to makes what you please...
public T this[int index]
{
get {return values[index]; }
}
I think your problem is that you have not overridden ToString in your customer class. Do that -- it will define how the objects should be displayed in the console.
Your actual problem aside for a moment, I would like to mention that there is no place for a ShowAll method in an array implementation. Why should an array be tied to a console application? Wouldn't you want to reuse it for a Windows Forms application oneday without the need to rewrite it?
Next, .NET already has a List<T> which does dynamic allocation as necessary. If you do want to write it again yourself, at least allocate the array in bigger steps (n*2 each time).
To remove the ShowAll method from the array (where it doesn't belong), you should consider taking one of the following approaches:
a) Create an extension method which works for any IEnumerable<T> (a List, Array, Collection, whatever):
public static class EnumExt
{
public static void ShowAll<T>(this IEnumerable<T> list)
{
foreach (T item in list)
Console.WriteLine(item);
}
}
Usage:
int[] array = new int[] { 1,2,3};
array.ShowAll();
b) Or, be even more abstract and create a ForEach extension method where you will pass an arbitrary delegate to perform actual work:
public static class EnumExt
{
public static void ForEach<T>(this IEnumerable<T> list, Action<T> action)
{
foreach (T item in list)
action(item);
}
}
Usage:
int[] array = new int[] { 1,2,3};
// now you are reusing the iterator
// for any action you want to execute
array.ForEach(Console.WriteLine);
// or
array.ForEach(item => Console.WriteLine("My item is: " + item));
I have two classes, CheckboxItemsList which extends a generic list, and CheckboxItems, which contains a list of objects of type CheckboxItem.
I want to use LINQ to be able to filter CheckboxItemsList based on properties of its CheckboxItems objects. The return type is always a generic list, though, but I want it to be a CheckboxItemsList.
So I guess the basic question is, can linq be made to return a list of the same type that it starts with? Since I can't cast a base class to a derived class, do I have any option other than iterating through the results of the linq query and rebuilding the derived list object row by row? Not that this is the end of the world, but I'm relatively new to linq and was wondering it there is a better way to do it.
What I want:
CheckboxItemsList newList = MyCheckboxItemsList.Where(item=>item.Changed);
(obviously doesn't work since the query will return List<CheckboxItems>, not CheckboxItemsList)
The objects, generally:
public class CheckboxItemsList: List<CheckboxItems>
{
// does not add any fields, just access methods
}
public class CheckboxItems : IEnumerable<CheckboxItem>
{
public long PrimaryKey=0;
protected CheckboxItem[] InnerList;
public bool Changed
{
get {
return (InnerList.Any(item => item.Changed));
}
}
....
}
No, this is not possible out of the box. You'll need to add code to do this.
For example, you can add a constructor like so:
public CheckboxItemsList(IEnumerable<CheckboxItems> checkboxItems) {
// something happens
}
Then you can say
CheckboxItemsList newList = new CheckboxItemsList(
MyCheckboxItemsList.Where(item => item.Changed)
);
Additionally, you could add an extension method like so
static class IEnumerableCheckboxItemsExtensions {
public static ToCheckboxItemsList(
this IEnumerable<CheckboxItems> checkboxItems
) {
return new CheckboxItemsList(checkboxItems);
}
}
and then
CheckboxItemsList newList =
MyCheckboxItemsList.Where(item => item.Changed)
.ToCheckboxItemsList();
LINQ works on IEnumerable<T> and IQueryable<T> and the result types of all LINQ operations (Where, Select) etc, will return one of those. The standard ToList function returns a concrete list of type List<T>, you may need to come up with an extension method, e.g.:
public static CheckboxItemsList ToItemList(this IEnumerable<CheckboxItem> enumerable)
{
return new CheckboxItemsList(enumerable);
}
No, there's no built-in way to do this. You have two main options:
Add a constructor to your CheckboxItemsList class that takes an IEnumerable<CheckboxItems> or similar. Pass that collection on to the base List<T> constructor that takes an IEnumerable<T>. That base constructor should then populate the list for you:
var newList =
new CheckboxItemsList(MyCheckboxItemsList.Where(item=>item.Changed));
// ...
public class CheckboxItemsList : List<CheckboxItems>
{
public CheckboxItemsList(IEnumerable<CheckboxItems> collection)
: base(collection)
{
}
}
Create an extension method that takes an IEnumerable<CheckboxItems> or similar and returns a populated CheckboxItemsList:
var newList = MyCheckboxItemsList.Where(item=>item.Changed)
.ToCheckboxItemsList();
// ...
public static class EnumerableExtensions
{
public static CheckboxItemsList ToCheckboxItemsList(
this IEnumerable<CheckboxItems> source)
{
var list = new CheckboxItemsList();
foreach (T item in source)
{
list.Add(item);
}
return list;
}
}
(Of course, for completeness you could implement both of these options. The extension method would then just pass its IEnumerable<CheckboxItems> argument on to the constructor rather than manually looping and adding each item.)
You can also use "Conversion Operator", as below:
public class CheckboxItemsList: List<CheckboxItems>
{
public static implicit operator CheckboxItems(IEnumerable<CheckboxItems> items)
{
var list = new CheckboxItemsList();
foreach (var item in items)
{
list.Add(item);
}
return list;
}
}
Now, the below code would work.
CheckboxItemsList newList = MyCheckboxItemsList.Where(item=>item.Changed);
From MSDN:
A conversion operator declaration that includes the implicit keyword introduces a user-defined implicit conversion. Implicit conversions can occur in a variety of situations, including function member invocations, cast expressions, and assignments. This is described further in Section 6.1.
A conversion operator declaration that includes the explicit keyword introduces a user-defined explicit conversion. Explicit conversions can occur in cast expressions, and are described further in Section 6.2.
Here is what I came up with, building on the various suggestions of others. A generic extension method:
public static T ToList<T>(this IEnumerable baseList) where T : IList,new()
{
T newList = new T();
foreach (object obj in baseList)
{
newList.Add(obj);
}
return (newList);
}
So now I can do what I want:
CheckboxItemsList newList = MyCheckboxItemsList.Where(item=>item.Changed)
.ToList<CheckboxItemsList>();
Another pretty obvious solution occurred to me, which is also useful for situations where the derived list class has field properties that I need to maintain in the new list.
Just create a new instance of my derived list class, and use AddRange to populate it.
// When created with a CheckboxItemsList parameter, it creates a new empty
// list but copies fields
CheckboxItemsList newList = new CheckboxItemsList(OriginalList);
newList.AddRange(OriginalList.Where(item => item.Changed));
I've got a method that computes a list. At certain points in the algorithm a single element from the list needs to be chosen. It doesn't really matter which element is chosen, but I'd like to leave it up to the user to decide.
Right now, I've added an extension method IList<T>.Random() which simply takes a random element. .First() would have worked equally as well. Supposing I want to let the user pick which method is used, or perhaps an entirely different method, how would that look?
I was thinking about using an enum with limited options, and then I could wrap each of these calls in a switch and call the appropriate function. But maybe some sort of lambda function would be more appropriate?
This method needs to be used in two different places, once on a List<char> and once on a List<string>. I want to use the same method for both.
This isn't a GUI app. I'm trying to decide how to design the API.
Specifically, I want to have a field like
public Func<IList<T>, T> SelectElement = list => list.First();
Which would then be used in the method,
public string Reverse(string pattern, IList<object> args = null, IDictionary<string, object> kwargs = null)
But generic fields aren't possible. So I'm looking for an alternative solution. One would be to make the SelectElement method an argument to Reverse(), then I could make it generic... but I was hoping to keep it at a class-level for re-usability. Don't want to pass any more args to the function if I can help it.
Edit: full source code
how about this:
public class MyClass
{
public static class C<T>
{
public static Func<IList<T>, T> SelectElement;
}
public int Test(IList<int> list)
{
return C<int>.SelectElement(list);
}
}
static class Program
{
static void Main(string[] args)
{
MyClass.C<char>.SelectElement = xs => xs.First();
MyClass.C<int>.SelectElement = xs => xs.First();
var list = new List<int>(new int[] { 1, 2, 3 });
var c = new MyClass();
var v = c.Test(list);
Console.WriteLine(v);
}
}
Here's an extremely basic example I put together using a generic method that takes in a Func<IEnumerable<T>, T> for selecting an item from the list and then returns the result. I've done a few examples of how to call it:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Test
{
class Program
{
static void Main(string[] args)
{
//Simple list.
var list = new List<int> { 1, 2, 3, 4 };
// Try it with first
var result = DoItemSelect(list, Enumerable.First);
Console.WriteLine(result);
// Try it with last
result = DoItemSelect(list, Enumerable.Last);
Console.WriteLine(result);
// Try it with ElementAt for the second item (index 1) in the list.
result = DoItemSelect(list, enumerable => enumerable.ElementAt(1));
Console.WriteLine(result);
}
public static T DoItemSelect<T>(IEnumerable<T> enumerable, Func<IEnumerable<T>, T> selector)
{
// You can do whatever you method does here, selector is the user specified func for
// how to select from the enumerable. Here I just return the result of selector directly.
return selector(enumerable);
}
}
}
If you want to limit the choices a user has you could follow the route of an enum and make this method a private method and then have a way to convert the enum to the appropriate selector delegate to pass to the underlying private method.
public Func<IList<object>, object> SelectElement = list => list.First();
private T _S<T>(IEnumerable<T> list)
{
return (T)SelectElement(list.Cast<object>().ToList());
}
I can make the anonymous method work on objects, thereby avoiding generics, and then add a helper method which is what I'll actually use to call it. A little ugly, but seems to work.
This works for chars and strings. Haven't tested with other types. Built this before I saw Ralph's code, which is practically the same.
LINQPad code:
void Main()
{
var chars = new List<char>();
var strings = new List<string>();
chars.AddRange(new char[] {'1','2','4','7','8','3'});
strings.AddRange(new string[] {"01","02","09","12","28","52"});
chars.Dump();
strings.Dump();
Func<IList<object>, string> SelectFirst = ( list )
=> list.First().ToString();
Func<IList<object>, string> SelectLast = ( list )
=> list.Last().ToString();
Func<IList<object>, string> SelectRandom = ( list )
=> list.ElementAt( new Random().Next(0, list.Count())).ToString();
SelectBy(SelectFirst, strings.Cast<object>().ToList()).Dump();
SelectBy(SelectFirst, chars.Cast<object>().ToList()).Dump();
SelectBy(SelectLast, strings.Cast<object>().ToList()).Dump();
SelectBy(SelectLast, chars.Cast<object>().ToList()).Dump();
SelectBy(SelectRandom, strings.Cast<object>().ToList()).Dump();
SelectBy(SelectRandom, chars.Cast<object>().ToList()).Dump();
}
private string SelectBy(Func<IList<object>, string> func, IList<object> list)
{
return func(list);
}