Fixed container, enumerable, intellisense indexable (or member) - c#

I'm trying to make an object to hold some strings. The object can be anything, including collections, arrays ... The strings need to be enumerable (IEnumerable or similar). Each string indexer needs to be known by intellisense and Reflection is a last option. One single object, no separate object for indexers.
Example usage:
public static class features
{
public const string favorite = "blue background";
public const string nice = "animation";
}
public static class Program
{
public static void Main()
{
foreach (string feature in features)
{
Console.WriteLine(feature);
}
//... select a feature
Console.WriteLine(features.favorite);
}
}
EDIT:
I will use the first solution proposed by Jim Mischel, modified to use reflection, as that gets the advantages I'm interested in at the current time.
encapsulates everything in one entity
names are directly associated with values
enumerator is dynamic
public IEnumerator<string> GetEnumerator()
{
FieldInfo[] strings = this.GetType().GetFields();
foreach (FieldInfo currentField in strings)
{
yield return currentField.GetValue(null).ToString();
}
yield break;
}
I thank everyone for your effort.

Offhand, I can think of two ways to do it. However, since it must be IEnumerable<string> it can't be a static class because static classes can't implement interfaces. Nor can static methods implement interface methods.
The first way uses constants and an enumerator that just returns them in order:
public class Features: IEnumerable<string>
{
public const string Favorite = "blue background";
public const string Nice = "animation";
public IEnumerator<string> GetEnumerator()
{
yield return Favorite;
yield return Nice;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
The second way stores the values in an array and uses an enum for the indexes. The enumerator just returns the enumerator for the array. Again, this is not static because of the enumerator, and also because indexers can't be static.
public enum FeaturesIndex
{
Favorite = 0,
Nice = 1
}
public class Features2 : IEnumerable<string>
{
private static readonly string[] _features = new string[]
{
"blue background",
"animation"
};
public string this [FeaturesIndex ix]
{
get { return _features[(int) ix]; }
}
public IEnumerator<string> GetEnumerator()
{
return ((IEnumerable<string>) _features).GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
A third possibility, as pointed out by others, is using a dictionary and either an enumeration or defined constants as keys. It's an interesting approach, the only potential drawback being that you can't guarantee the order in which keys will be returned when you enumerate the collection. If that's a problem, you could have your enumerator sort the sequence before returning.
Any way you look at it, there are tradeoffs. Both of my solutions require manual synchronization of keys and values. In the first, you have to make sure that the enumerator retures all of the values. In the second, you have to ensure that your enum matches the array.
Pick your poison.
It also depends on how you're going to use the thing. My first solution has the benefit of simplicity and would probably be quite acceptable if it's a write-once, use-forever kind of thing. The second option has the benefit of using an indexer, which is more commonly associated with collections.

There are many better ways to do this. To follow a similar pattern to what you're looking for, here's one way of doing it:
public static class features
{
public enum TYPES { favorite, nice }
public static Dictionary<TYPES,string> values = new Dictionary<TYPES,string>() {
{ TYPES.favorite, "blue background" },
{ TYPES.nice, "animation" } };
}
public static class Program
{
public static void Main()
{
foreach (string feature in features.values.keys)
{
Console.WriteLine(features.values[feature]);
}
//... select a feature
Console.WriteLine(features.values[TYPES.favorite]);
}
}

So really what you are asking for is an object with Properties you can change and is also enumerable, but makes it so you don't need to call reflection to enumerate unless absolutely necessary.
If what I assume you are actually looking is the following
public class Features: IEnumerable<string>
{
private readonly Dictionary<string,string> _internalCollection;
public Features()
{
_internalCollection = new Dictionary<string,string>();
}
private string GetByKey(string id)
{
if(!_internalCollection.ContainsKey(id))
return null;
return _internalCollection[id];
}
private void SetByKey(string id, string value)
{
_internalCollection[id]=value;
}
const string _favoriteId = "favorite";
public string Favorite
{
get { return GetByKey(_favoriteId); }
set { return SetByKey(_favoriteId,value);}
}
const string _niceId = "nice";
public string Nice
{
get { return GetByKey(_niceId);}
set { return SetByKey(_niceId, value);}
}
public string this[string index]
{
get { return GetByKey(index.ToLower()); }
set { return SetByKey(index.ToLower(), value);}
}
public IEnumerator<string> GetEnumerator()
{
foreach(var key in _internalCollection.Keys)
yield return _internalCollection[key];
yield break;
}
}

Related

What is the "type" of a generic IList<T>?

Imagine an extension like this..
public static Blah<T>(this IList<T> ra)
{
..
}
Imagine you want to make a note of the most recently-called one.
private static IList recent;
public static Blah<T>(this IList<T> ra)
{
recent = ra;
..
}
You actually can not do that:
error CS0266: Cannot implicitly convert type System.Collections.Generic.IList<T> to System.Collections.IList.
1- You can simply make recent an object and that seems to work fine, but it seems like a poor solution.
2- It seems if you do have recent as an IList, you can actually cast the "ra" to that...
recent = (System.Collections.IList)ra;
and it seems to work. Seems strange though?? So,
3- Actually, what type should recent be so that you don't have to cast to it?? How can you make recent the same type as ra? You can't say this ....
private static System.Collections.Generic.IList recent;
it's not meaningful. So what the heck is the type of "ra"? What should recent "be" so that you can simply say recent=ra ?
(I mention this is for Unity, since you constantly use generic extensions in Unity.)
4- Consider a a further difficulty the case if you want to have a Dictionary of them all.
private static Dictionary<object,int> recents = new Dictionary<object,int>();
I can really only see how to do it as an object.
USE CASE EXAMPLE.
Here's an extension you use constantly, everywhere, in game engineering,
public static T AnyOne<T>(this IList<T> ra)
{
int k = ra.Count;
if (k<=0) {Debug.Log("Warn!"+k);}
int r = UnityEngine.Random.Range(0,k);
return ra[r];
}
no problem so far. So,
explosions.AnyOne();
yetAnotherEnemyToDefeat = dinosaurStyles.AnyOne();
and so on. However. Of course, actual random selections feel bad; in practice what you want is a fairly non-repeating order, more like a shuffle. Usually the best thing to do with any list or array is shuffle them, and serve them in that order; perhaps shuffle again each time through. Simple example, you have 20 random sound effects roars , being for when the dino roars. Each time you need one, if you do this
roars.AnyOne();
its OK, but not great. It will sound sort of suck. (Most players will report it as "not being random" or "repeating a lot".) This
roars.NextOne();
is much better. So, NextOne() should, on its own, (a) if we're at the start shuffle the list, (b) serve it in that order, (c) perhaps shuffle it again each time you use up the list. {There are further subtleties, eg, try not to repeat any near the end/start of the reshuffle, but irrelevant here.}
Note that subclassing List (and/or array) would suck for many obvious reasons, it's a job for a simple self-contained extension.
So then, here's a beautiful way to implement NextOne() using a simple stateful extension.
private static Dictionary<object,int> nextOne = new Dictionary<object,int>();
public static T NextOne<T>(this IList<T> ra)
{
if ( ! nextOne.ContainsKey(ra) )
// i.e., we've never heard about this "ra" before
nextOne.Add(ra,0);
int index = nextOne[ra];
// time to shuffle?
if (index==0)
{
Debug.Log("shuffling!"); // be careful to mutate, don't change the ra!
IList<T> temp = ra.OrderBy(r => UnityEngine.Random.value).ToList();
ra.Clear(); foreach(T t in temp) ra.Add(t);
}
T result = ra[index];
++index;
index=index%ra.Count;
nextOne[ra] = index;
return result;
}
This is surely the perfect example of a "stateful extension".
Notice indeed, I just used "object".
I guess in a way, the fundamental question in this QA is, is it best to use the Dictionary of "object" there, or, would something else more typey be better? Really that's the question at hand. Cheers!
If you want a single globally most recent IList<T> where T potentially varies each time, then your only options are to use object or dynamic. Both require casting; the latter just casts automatically.
I think your confusion stems from thinking that IList<T> inherits IList - it doesn't:
public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable
So arguably you could do this, although I don't see any advantage really:
private static IEnumerable recent;
public static void Blah<T>(this IList<T> ra)
{
recent = ra;
...
}
The simplest, and most type-safe, solution is to store a separate value for each T:
private static class RecentHolder<T> {
public static IList<T> Value { get; set; }
}
public static Blah<T>(this IList<T> ra) {
RecentHolder<T>.Value = ra;
}
What is the “type” of a generic IList< T >?
The base type..
Console.WriteLine( new List<int>().GetType().BaseType);
System.Object
The Generic Type definition ...
Console.WriteLine( new List<int>().GetType().GetGenericTypeDefinition());
System.Collections.Generic.List`1[T]
And to expand on SLAKS Answer
Not really. In the absence of a separate common non-generic base class
You can also use interfaces. So you could do...
public interface IName
{
string Name { get; set; }
}
public class Person : IName
{
public string Name { get; set; }
}
public class Dog : IName
{
public string Name { get; set; }
}
Then you could
private static List<IName> recent;
public static Blah<T>(this List<IName> ra)
{
recent = ra;
..
}
and it won't matter if you put Dog or Person in the list.
OR
I can't believe I didn't think about this last night; LINQ to the rescue using object.
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
private static class WonkyCache
{
private static List<object> cache = new List<object>();
public static void Add(object myItem)
{
cache.Add(myItem);
}
public static IEnumerable<T> Get<T>()
{
var result = cache.OfType<T>().ToList();
return result;
}
}
public static void Main()
{
WonkyCache.Add(1);
WonkyCache.Add(2);
WonkyCache.Add(3);
WonkyCache.Add(Guid.NewGuid());
WonkyCache.Add("George");
WonkyCache.Add("Abraham");
var numbers = WonkyCache.Get<int>();
Console.WriteLine(numbers.GetType());
foreach(var number in numbers)
{
Console.WriteLine(number);
}
var strings = WonkyCache.Get<string>();
Console.WriteLine(strings.GetType());
foreach(var s in strings)
{
Console.WriteLine(s);
}
}
}
Results:
System.Collections.Generic.List`1[System.Int32]
1
2
3
System.Collections.Generic.List`1[System.String]
George
Abraham
Try:
public static class StatefulRandomizer<T>
// Use IEquatable<T> for Intersect()
where T : IEquatable<T>
{
// this could be enhanced to be a percentage
// of elements instead of hardcoded
private static Stack<T> _memory = new Stack<T>();
private static IEnumerable<T> _cache;
public static void UpdateWith(IEnumerable<T> newCache)
{
_cache = newCache.ToList();
// Setup the stack again, keep only ones that match
var matching = _memory.Intersect(newCache);
_memory = new Stack<T>(matching);
}
public static T GetNextNonRepeatingRandom()
{
var nonrepeaters = _cache
.Except(_memory);
// Not familar with unity.. but this should make
// sense what I am doing
var next = nonrepeaters.ElementAt(UnityEngine.Random(0, nonrepeaters.Count()-1));
// this fast, Stack will know it's count so no GetEnumerator()
// and _cache List is the same (Count() will call List.Count)
if (_memory.Count > _cache.Count() / 2)
{
_memory.Pop();
}
_memory.Push(next);
return next;
}
}

Generic type's causing issue C#.net

I have class called GroupItem, i can store any type here say int, string, decimal, datetime etc.., Then, i have GroupItems which will store any groupItem. I'm using an arraylist to store all the groupItem.
public class GroupItem<T>
{
private string heading;
private List<T> items = new List<T>();
public GroupItem() { }
public string Heading
{
get { return heading; }
set { heading = value; }
}
public List<T> Items
{
get { return items; }
set { items = value; }
}
public void Add(T value)
{
this.items.Add(value);
}
public T this[int index]
{
get
{
return this.items[index];
}
}
}
public class GroupItems
{
private string groupName;
private List<object> items = new List<object>();
public string GroupName
{
get { return groupName; }
set { groupName = value; }
}
public GroupItems() { }
public void Add(object value)
{
this.items.Add(value);
}
public object this[int index]
{
get
{
return this.items[index];
}
}
}
I want to retrieve from GroupItems. How i can get generic item's values in groupItems?
I'm now inserting two items, datetime and int to groupitems. Now i want to retrieve groupitems[2] value but how i can convert this to groupItem without knowing what it is. Even we may get its genericarguments by getType().getGenericarguments()[0]. But how i can create an instance based upon that.
If the list is storing heterogeneous items, then I would suggest you need a common non-generic interface or base-class. So, say we have
interface IGroupItem {
// the non-generic members, and maybe
// "object Value {get;}" etc, and maybe
// "Type ItemTypr {get;}"
}
You would then have:
class GroupItem<T> : IGroupItem {...}
an you would then use
List<IGroupItem> ...
instead of ArrayList, or, franky, in place of GroupItems {...}
What I'd do is create a generic collection such as:
public class GroupItems<T> : List<GroupItem<T>>
{
}
If you need to extend the basic functionality of a list, you could also extend Collection<T> and override the methods you need:
public class GroupItems<T> : Collection<GroupItem<T>>
{
protected override void InsertItem(int index, T item)
{
// your custom code here
// ...
// and the actual insertion
base.InsertItem(index, item);
}
}
How about just replacing your GroupItems class with List<GroupItem<T>> ?
Depending on what you do with GroupItem you should either inherit from List/Collection as was offered by other or use a generic collection inside your class
e.g.
class GroupItem<T>
{
private List<T> items = new List<T>();
public void Add(T value)
{
items.Add(value);
}
public T Get()
{
//replace with some logic to detemine what to get
return items.First();
}
}
There are two situations that could be covered by your question:
You want to simply store a collection of GroupItem's of type T in the class GroupItems.
You want to store a collection of generic GroupItem's of any type in the class GroupItems. To better clarify, I mean that you could store GroupItem<DateTime> or GroupItem<int> in the same GroupItems class.
Here are some ways of going about storing and retrieving for both scenarios:
Same Type
public class GroupItem<T>
{
// ... Code for GroupItem<T>
}
public class GroupItems<T>
{
private List<GroupItem<T>> mItems = new List<GroupItem<T>>();
public void Add(T item)
{
mItems.Add(item);
}
public T GetItem(int index)
{
return mItems[index];
}
}
Here you will build a collections that contain GroupItem's of the same time, so a collection of GroupItem<DateTime> for example. All the items will be of the same type.
Generic Type
public interface IGroupItem
{
// ... Common GroupItem properties and methods
}
public class GroupItem<T>
{
// ... Code for GroupItem<T>
}
public class GroupItems
{
private List<IGroupItem> mItems = new List<IGroupItem>();
public void Add(IGroupItem item)
{
mItems.Add(item);
}
// This is a generic method to retrieve just any group item.
public IGroupItem GetItem(int index)
{
return mItems[index];
}
// This is a method that will get a group item at the specified index
// and then cast it to the specific group item type container.
public GroupItem<T> GetItem<T>(int index)
{
return (GroupItem<T>)mItems[index];
}
}
Here you will be able to build and maintain a single collection that can contain any GroupItem with any Type. So you could have a GroupItems collection that contains items of GroupItem<DateTime>, GroupItem<int>, etc.
Please note that none of these code examples take into account any erroneous circumstances.
Consider: you have a collection of items; the items may have any runtime type (string, int, etc.). Because of this, the static type of the collections items must be object.
It seems that you want to be able to retrieve items from the list with strong static typing. That's not possible without a lot of conditional logic (or reflection). For example:
object item = collection[0];
if (item is int)
//do something with an int
else if (item is string)
//do something with a string
Now suppose instead of "doing something" with the value of collection[0], we assign the value to a variable. We can do one of two things:
use the same variable for both cases, in which case the static type must be object.
use separate variables, in which case the static type will be string or int, but outside of the conditional logic, we can't know which variable holds the value of collection[0].
Neither option really solves the problem.
By creating GroupItem<T>, you add a level of indirection to this problem, but the underlying problem is still there. As an exercise, try reworking the example, but starting from "Consider: you have a collection of items; the items are of type GroupItem<T> where T may be any runtime type (string, int, etc.)."
Thanks for your inputs.
I have resolved it myself using multiple overloading methods to resolve this.
for example:
private void Print(GroupItem<string> items)
{
///custom coding
}
private void Print(GroupItem<int> items)
{
///custom coding
}
Though its not efficient enough, i want to do in this way as it was .net 2.0.
I'm now improving this in .Net 4.0 with new algorithm.
Thanks a lot for all of your helps.

c# - how do square brackets in a method declaration fit in with c#?

How do square brackets in a method declaration fit in with c#? That is I see when reading up on WPF validation one can use IDataErrorInfo with an example of the following.
public string this[string propertyName]
// Error handling takes place here.
public string this[string propertyName] // <== IE HERE
{
get
// etc
}
}
I note MSDN says "Square brackets ([]) are used for arrays, indexers, and attributes. They can also be used with pointers." So is the above usage a pointer?
This is a standard feature of the C# language called an Indexer. Generally you would use these when writing your own collections, or similar types. Here is a brief (not real world) example.
public class Foo {
private List<int> m_Numbers = new List<int>();
public int this[int index] {
get {
return m_Numbers[index];
}
set {
m_Numbers[index] = value;
}
}
}
class Program {
static void Main() {
Foo foo = new Foo();
foo[0] = 1;
}
}
There's a lot of cool things you can use indexers for if you are creative, it's a really neat feature of the language.
This is a declaration of an Indexer. It's analagous to array indexing. propertyName is a string which the method uses to index into some kind of collection. The method returns the corresponding string from the collection.
Of course, the method could do something else, but that's what the semantics mean.
That would be an indexer property. They're useful on custom collections:
public class MyCustomCollection
{
List<MyObject> _list = new List<MyObject>();
public string this[string name]
{
get { return _list.Single(o => o.Name == name)
.Select(o => o.Description);
}
public string this[int id]
{
get { return _list.Single(o => o.Id == id).Select(o => o.Description);
}
}
And then you can use the collection like:
MyCollection col = new MyCollection();
// Fill the collection
string description = col["Name"];
string description2 = col[2];

Passing a single item as IEnumerable<T>

Is there a common way to pass a single item of type T to a method which expects an IEnumerable<T> parameter? Language is C#, framework version 2.0.
Currently I am using a helper method (it's .Net 2.0, so I have a whole bunch of casting/projecting helper methods similar to LINQ), but this just seems silly:
public static class IEnumerableExt
{
// usage: IEnumerableExt.FromSingleItem(someObject);
public static IEnumerable<T> FromSingleItem<T>(T item)
{
yield return item;
}
}
Other way would of course be to create and populate a List<T> or an Array and pass it instead of IEnumerable<T>.
[Edit] As an extension method it might be named:
public static class IEnumerableExt
{
// usage: someObject.SingleItemAsEnumerable();
public static IEnumerable<T> SingleItemAsEnumerable<T>(this T item)
{
yield return item;
}
}
Am I missing something here?
[Edit2] We found someObject.Yield() (as #Peter suggested in the comments below) to be the best name for this extension method, mainly for brevity, so here it is along with the XML comment if anyone wants to grab it:
public static class IEnumerableExt
{
/// <summary>
/// Wraps this object instance into an IEnumerable<T>
/// consisting of a single item.
/// </summary>
/// <typeparam name="T"> Type of the object. </typeparam>
/// <param name="item"> The instance that will be wrapped. </param>
/// <returns> An IEnumerable<T> consisting of a single item. </returns>
public static IEnumerable<T> Yield<T>(this T item)
{
yield return item;
}
}
Well, if the method expects an IEnumerable you've got to pass something that is a list, even if it contains one element only.
passing
new[] { item }
as the argument should be enough I think
In C# 3.0 you can utilize the System.Linq.Enumerable class:
// using System.Linq
Enumerable.Repeat(item, 1);
This will create a new IEnumerable that only contains your item.
Your helper method is the cleanest way to do it, IMO. If you pass in a list or an array, then an unscrupulous piece of code could cast it and change the contents, leading to odd behaviour in some situations. You could use a read-only collection, but that's likely to involve even more wrapping. I think your solution is as neat as it gets.
In C# 3 (I know you said 2), you can write a generic extension method which might make the syntax a little more acceptable:
static class IEnumerableExtensions
{
public static IEnumerable<T> ToEnumerable<T>(this T item)
{
yield return item;
}
}
client code is then item.ToEnumerable().
This helper method works for item or many.
public static IEnumerable<T> ToEnumerable<T>(params T[] items)
{
return items;
}
I'm kind of surprised that no one suggested a new overload of the method with an argument of type T to simplify the client API.
public void DoSomething<T>(IEnumerable<T> list)
{
// Do Something
}
public void DoSomething<T>(T item)
{
DoSomething(new T[] { item });
}
Now your client code can just do this:
MyItem item = new MyItem();
Obj.DoSomething(item);
or with a list:
List<MyItem> itemList = new List<MyItem>();
Obj.DoSomething(itemList);
Either (as has previously been said)
MyMethodThatExpectsAnIEnumerable(new[] { myObject });
or
MyMethodThatExpectsAnIEnumerable(Enumerable.Repeat(myObject, 1));
As a side note, the last version can also be nice if you want an empty list of an anonymous object, e.g.
var x = MyMethodThatExpectsAnIEnumerable(Enumerable.Repeat(new { a = 0, b = "x" }, 0));
I agree with #EarthEngine's comments to the original post, which is that 'AsSingleton' is a better name. See this wikipedia entry. Then it follows from the definition of singleton that if a null value is passed as an argument that 'AsSingleton' should return an IEnumerable with a single null value instead of an empty IEnumerable which would settle the if (item == null) yield break; debate. I think the best solution is to have two methods: 'AsSingleton' and 'AsSingletonOrEmpty'; where, in the event that a null is passed as an argument, 'AsSingleton' will return a single null value and 'AsSingletonOrEmpty' will return an empty IEnumerable. Like this:
public static IEnumerable<T> AsSingletonOrEmpty<T>(this T source)
{
if (source == null)
{
yield break;
}
else
{
yield return source;
}
}
public static IEnumerable<T> AsSingleton<T>(this T source)
{
yield return source;
}
Then, these would, more or less, be analogous to the 'First' and 'FirstOrDefault' extension methods on IEnumerable which just feels right.
This is 30% faster than yield or Enumerable.Repeat when used in foreach due to this C# compiler optimization, and of the same performance in other cases.
public struct SingleSequence<T> : IEnumerable<T> {
public struct SingleEnumerator : IEnumerator<T> {
private readonly SingleSequence<T> _parent;
private bool _couldMove;
public SingleEnumerator(ref SingleSequence<T> parent) {
_parent = parent;
_couldMove = true;
}
public T Current => _parent._value;
object IEnumerator.Current => Current;
public void Dispose() { }
public bool MoveNext() {
if (!_couldMove) return false;
_couldMove = false;
return true;
}
public void Reset() {
_couldMove = true;
}
}
private readonly T _value;
public SingleSequence(T value) {
_value = value;
}
public IEnumerator<T> GetEnumerator() {
return new SingleEnumerator(ref this);
}
IEnumerator IEnumerable.GetEnumerator() {
return new SingleEnumerator(ref this);
}
}
in this test:
// Fastest among seqs, but still 30x times slower than direct sum
// 49 mops vs 37 mops for yield, or c.30% faster
[Test]
public void SingleSequenceStructForEach() {
var sw = new Stopwatch();
sw.Start();
long sum = 0;
for (var i = 0; i < 100000000; i++) {
foreach (var single in new SingleSequence<int>(i)) {
sum += single;
}
}
sw.Stop();
Console.WriteLine($"Elapsed {sw.ElapsedMilliseconds}");
Console.WriteLine($"Mops {100000.0 / sw.ElapsedMilliseconds * 1.0}");
}
As I have just found, and seen that user LukeH suggested too, a nice simple way of doing this is as follows:
public static void PerformAction(params YourType[] items)
{
// Forward call to IEnumerable overload
PerformAction(items.AsEnumerable());
}
public static void PerformAction(IEnumerable<YourType> items)
{
foreach (YourType item in items)
{
// Do stuff
}
}
This pattern will allow you to call the same functionality in a multitude of ways: a single item; multiple items (comma-separated); an array; a list; an enumeration, etc.
I'm not 100% sure on the efficiency of using the AsEnumerable method though, but it does work a treat.
Update: The AsEnumerable function looks pretty efficient! (reference)
Although it's overkill for one method, I believe some people may find the Interactive Extensions useful.
The Interactive Extensions (Ix) from Microsoft includes the following method.
public static IEnumerable<TResult> Return<TResult>(TResult value)
{
yield return value;
}
Which can be utilized like so:
var result = EnumerableEx.Return(0);
Ix adds new functionality not found in the original Linq extension methods, and is a direct result of creating the Reactive Extensions (Rx).
Think, Linq Extension Methods + Ix = Rx for IEnumerable.
You can find both Rx and Ix on CodePlex.
I recently asked the same thing on another post
Is there a way to call a C# method requiring an IEnumerable<T> with a single value? ...with benchmarking.
I wanted people stopping by here to see the brief benchmark comparison shown at that newer post for 4 of the approaches presented in these answers.
It seems that simply writing new[] { x } in the arguments to the method is the shortest and fastest solution.
This may not be any better but it's kind of cool:
Enumerable.Range(0, 1).Select(i => item);
Sometimes I do this, when I'm feeling impish:
"_".Select(_ => 3.14) // or whatever; any type is fine
This is the same thing with less shift key presses, heh:
from _ in "_" select 3.14
For a utility function I find this to be the least verbose, or at least more self-documenting than an array, although it'll let multiple values slide; as a plus it can be defined as a local function:
static IEnumerable<T> Enumerate (params T[] v) => v;
// usage:
IEnumerable<double> example = Enumerate(1.234);
Here are all of the other ways I was able to think of (runnable here):
using System;
using System.Collections.Generic;
using System.Linq;
public class Program {
public static IEnumerable<T> ToEnumerable1 <T> (T v) {
yield return v;
}
public static T[] ToEnumerable2 <T> (params T[] vs) => vs;
public static void Main () {
static IEnumerable<T> ToEnumerable3 <T> (params T[] v) => v;
p( new string[] { "three" } );
p( new List<string> { "three" } );
p( ToEnumerable1("three") ); // our utility function (yield return)
p( ToEnumerable2("three") ); // our utility function (params)
p( ToEnumerable3("three") ); // our local utility function (params)
p( Enumerable.Empty<string>().Append("three") );
p( Enumerable.Empty<string>().DefaultIfEmpty("three") );
p( Enumerable.Empty<string>().Prepend("three") );
p( Enumerable.Range(3, 1) ); // only for int
p( Enumerable.Range(0, 1).Select(_ => "three") );
p( Enumerable.Repeat("three", 1) );
p( "_".Select(_ => "three") ); // doesn't have to be "_"; just any one character
p( "_".Select(_ => 3.3333) );
p( from _ in "_" select 3.0f );
p( "a" ); // only for char
// these weren't available for me to test (might not even be valid):
// new Microsoft.Extensions.Primitives.StringValues("three")
}
static void p <T> (IEnumerable<T> e) =>
Console.WriteLine(string.Join(' ', e.Select((v, k) => $"[{k}]={v,-8}:{v.GetType()}").DefaultIfEmpty("<empty>")));
}
For those wondering about performance, while #mattica has provided some benchmarking information in a similar question referenced above, My benchmark tests, however, have provided a different result.
In .NET 7, yield return value is ~9% faster than new T[] { value } and allocates 75% the amount of memory. In most cases, this is already hyper-performant and is as good as you'll ever need.
I was curious if a custom single collection implementation would be faster or more lightweight. It turns out because yield return is implemented as IEnumerator<T> and IEnumerable<T>, the only way to beat it in terms of allocation is to do that in my implementation as well.
If you're passing IEnumerable<> to an outside library, I would strongly recommend not doing this unless you're very familiar with what you're building. That being said, I made a very simple (not-reuse-safe) implementation which was able to beat the yield method by 5ns and allocated only half as much as the array.
Because all tests were passed an IEnumerable<T>, value types generally performed worse than reference types. The best implementation I had was actually the simplest - you can look at the SingleCollection class in the gist I linked to. (This was 2ns faster than yield return, but allocated 88% of what the array would, compared to the 75% allocated for yield return.)
TL:DR; if you care about speed, use yield return item. If you really care about speed, use a SingleCollection.
The easiest way I'd say would be new T[]{item};; there's no syntax to do this. The closest equivalent that I can think of is the params keyword, but of course that requires you to have access to the method definition and is only usable with arrays.
Enumerable.Range(1,1).Select(_ => {
//Do some stuff... side effects...
return item;
});
The above code is useful when using like
var existingOrNewObject = MyData.Where(myCondition)
.Concat(Enumerable.Range(1,1).Select(_ => {
//Create my object...
return item;
})).Take(1).First();
In the above code snippet there is no empty/null check, and it is guaranteed to have only one object returned without afraid of exceptions. Furthermore, because it is lazy, the closure will not be executed until it is proved there is no existing data fits the criteria.
To be filed under "Not necessarily a good solution, but still...a solution" or "Stupid LINQ tricks", you could combine Enumerable.Empty<>() with Enumerable.Append<>()...
IEnumerable<string> singleElementEnumerable = Enumerable.Empty<string>().Append("Hello, World!");
...or Enumerable.Prepend<>()...
IEnumerable<string> singleElementEnumerable = Enumerable.Empty<string>().Prepend("Hello, World!");
The latter two methods are available since .NET Framework 4.7.1 and .NET Core 1.0.
This is a workable solution if one were really intent on using existing methods instead of writing their own, though I'm undecided if this is more or less clear than the Enumerable.Repeat<>() solution. This is definitely longer code (partly due to type parameter inference not being possible for Empty<>()) and creates twice as many enumerator objects, however.
Rounding out this "Did you know these methods exist?" answer, Array.Empty<>() could be substituted for Enumerable.Empty<>(), but it's hard to argue that makes the situation...better.
I'm a bit late to the party but I'll share my way anyway.
My problem was that I wanted to bind the ItemSource or a WPF TreeView to a single object. The hierarchy looks like this:
Project > Plot(s) > Room(s)
There was always going to be only one Project but I still wanted to Show the project in the Tree, without having to pass a Collection with only that one object in it like some suggested.
Since you can only pass IEnumerable objects as ItemSource I decided to make my class IEnumerable:
public class ProjectClass : IEnumerable<ProjectClass>
{
private readonly SingleItemEnumerator<AufmassProjekt> enumerator;
...
public IEnumerator<ProjectClass > GetEnumerator() => this.enumerator;
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
}
And create my own Enumerator accordingly:
public class SingleItemEnumerator : IEnumerator
{
private bool hasMovedOnce;
public SingleItemEnumerator(object current)
{
this.Current = current;
}
public bool MoveNext()
{
if (this.hasMovedOnce) return false;
this.hasMovedOnce = true;
return true;
}
public void Reset()
{ }
public object Current { get; }
}
public class SingleItemEnumerator<T> : IEnumerator<T>
{
private bool hasMovedOnce;
public SingleItemEnumerator(T current)
{
this.Current = current;
}
public void Dispose() => (this.Current as IDisposable).Dispose();
public bool MoveNext()
{
if (this.hasMovedOnce) return false;
this.hasMovedOnce = true;
return true;
}
public void Reset()
{ }
public T Current { get; }
object IEnumerator.Current => this.Current;
}
This is probably not the "cleanest" solution but it worked for me.
EDIT
To uphold the single responsibility principle as #Groo pointed out I created a new wrapper class:
public class SingleItemWrapper : IEnumerable
{
private readonly SingleItemEnumerator enumerator;
public SingleItemWrapper(object item)
{
this.enumerator = new SingleItemEnumerator(item);
}
public object Item => this.enumerator.Current;
public IEnumerator GetEnumerator() => this.enumerator;
}
public class SingleItemWrapper<T> : IEnumerable<T>
{
private readonly SingleItemEnumerator<T> enumerator;
public SingleItemWrapper(T item)
{
this.enumerator = new SingleItemEnumerator<T>(item);
}
public T Item => this.enumerator.Current;
public IEnumerator<T> GetEnumerator() => this.enumerator;
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
}
Which I used like this
TreeView.ItemSource = new SingleItemWrapper(itemToWrap);
EDIT 2
I corrected a mistake with the MoveNext() method.
I prefer
public static IEnumerable<T> Collect<T>(this T item, params T[] otherItems)
{
yield return item;
foreach (var otherItem in otherItems)
{
yield return otherItem;
}
}
This lets you call item.Collect() if you want the singleton, but it also lets you call item.Collect(item2, item3) if you want

Using Property to get array element in C#

Is there a way to get a specific element (based in index) from a string array using Property. I prefer using public property in place of making the string array public. I am working on C#.NET 2.0
Regards
Are you possibly trying to protect the original array; do you mean you want a protective wrapper around the array, through "a Property" (not of its own)? I'm taking this shot at guessing the details of your question. Here's a wrapper implementation for a string array. The array cannot be directly access, but only through the wrapper's indexer.
using System;
public class ArrayWrapper {
private string[] _arr;
public ArrayWrapper(string[] arr) { //ctor
_arr = arr;
}
public string this[int i] { //indexer - read only
get {
return _arr[i];
}
}
}
// SAMPLE of using the wrapper
static class Sample_Caller_Code {
static void Main() {
ArrayWrapper wrapper = new ArrayWrapper(new[] { "this", "is", "a", "test" });
string strValue = wrapper[2]; // "a"
Console.Write(strValue);
}
}
If I understand correctly what you are asking, You can use an indexer.
Indexers (C# Programming Guide)
Edit: Now that I've read the others, maybe you can expose a property that returns a copy of the array?
If the property exposes the array:
string s = obj.ArrayProp[index];
If you mean "can I have an indexed property", then no - but you can have a property that is a type with an indexer:
static class Program
{
static void Main()
{
string s = ViaArray.SomeProp[1];
string t = ViaIndexer.SomeProp[1];
}
}
static class ViaArray
{
private static readonly string[] arr = { "abc", "def" };
public static string[] SomeProp { get { return arr; } }
}
static class ViaIndexer
{
private static readonly IndexedType obj = new IndexedType();
public static IndexedType SomeProp { get { return obj; } }
}
class IndexedType
{
private static readonly string[] arr = { "abc", "def" };
public string this[int index]
{
get { return arr[index]; }
}
}
What you need is a Property that can have input (an index).
There is only one property like that, called an Indexer.
Look it up on MSDN.
A shortcut: use a built in code snippet: go to your class and type 'indexer' then press tab twice. Viola!
Properties don't take parameters, so that won't be possible.
You can build a method, for instance
public string GetStringFromIndex(int i)
{
return myStringArray[i];
}
Of course you'll probably want to do some checking in the method, but you get the idea.
I'm assuming that you have a class that has a private string array and you want to be able to get at an element of the array as a property of your class.
public class Foo
{
private string[] bar;
public string FooBar
{
get { return bar.Length > 4 ? bar[4] : null; }
}
}
This seems horribly hacky, though, so I'm either not understanding what you want or there's probably a better way to do what you want, but we'd need to know more information.
Update: If you have the index of the element from somewhere else as you indicate in your comment, you could use an indexer or simply create a method that takes the index and returns the value. I'd reserve the indexer for a class that is itself a container and use the method route otherwise.
public string GetBar( int index )
{
return bar.Length > index ? bar[index] : null;
}
Just return the array from the property; the resulting object will behave as an array, so you can index it.
E.G.:
string s = object.Names[15]
What you're asking can be done, like so:
You can initialize an object that holds your array, giving you exactly what you need:
public class ArrayIndexer<T> {
private T[] myArrRef;
public ArrayIndexer(ref T[] arrRef) {
myArrRef = arrRef;
}
public T this [int index] {
get { return myArrRef[index]; }
}
}
Then, in your class:
public ArrayIndexer arr;
private SomeType[] _arr;
//Constructor:
public MyClass(){
arr = new ArrayIndexer<SomeType>(ref _arr);
}
Usage:
myClassObj.arr[2] // Gives the second item in the array.
Et Voila! An indexed property.

Categories

Resources