List of Anonymous objects? - c#

I have a class using the List class. When attempting to set up the Add function to add my anonymous type, all I get is errors.
I've been searching for hours and as best I can tell, every example I've seen is doing the same thing. So I don't understand what's wrong.
class fileHistory<Object> : List<Object>
{
public new void Add(DateTime ts, int st)
{
base.Add( new { timeStamp = ts; status = st;} );
}
}

You don't need a generic declaration in your class definition, and you also need to change semicolons to commas:
public class fileHistory : List<Object>
{
public new void Add(DateTime ts, int st)
{
base.Add( new { timeStamp = ts, status = st} );
}
}

Right, you can overwrite (not polymorphism! check I used the word overwrite instead of override) List<T>.Add(T) method, but I believe that you could solve your issue using composition instead of inheritance and your code will work flawlessly:
class fileHistory
{
private readonly List<object> _log = new List<object>();
public void Add(DateTime ts, int st)
{
_log.Add( new { timeStamp = ts; status = st;} );
}
}
BTW, I see three design flaws here:
Anonymous types aren't meant to your use case. If you are adding objects with these two properties and you do it in a concrete use case like yours, maybe you're using anonymous types because of your laziness of designing a class with 2 properties??? ;)
Because of #1, why you would create a list of objects using a generic list? It defeats the entire purpose of generics!!
I find a bad design decision hidding Add of List<T>. Use composition instead of inheritance in these cases. Also, I don't know why you're using identifier re-using with new keyword when C# supports method overloading. In List<T> there's no overload of Add with your input parameters...
My advise is: code isn't fancier because of using fancy syntactic sugar provided by C#. Sometimes you don't need it, and honestly, I believe this is the case.
For those who're worried about LINQ...
Any class might or might not implement IEnumerable<T>. The whole fileHistory class can be iterated with foreach or LINQ and its extension methods implementing IEnumerable<T>:
// Check that I dropped the lazy approach of using
// anonymous types!!
class fileHistory : IEnumerable<FileLog>
{
private readonly List<FileLog> _log = new List<FileLog>();
public IEnumerator<FileLog> GetEnumerator()
{
return _log.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _log.GetEnumerator();
}
public void Add(DateTime ts, int st)
{
_log.Add(new FileLog { timeStamp = ts; status = st;} );
}
}
...and now some class like this can be iterated even when using composition instead of inheritance:
new fileHistory().Where(log => log.DateTime < DateTime.Now);

class fileHistory<Object> : List<Object>
{
public new void Add(DateTime ts, int st)
{
// That's how it's supposed to be
base.Add(new { timeStamp = ts, status = st });
}
}
Hope I've helped!

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;
}
}

How could I achieve JQuery style method calls on IEnumerables in C#?

In JQuery you can write $('.my-class').hide() and it will call hide() on all the results. There's no for loop, no iterating, no LINQ extensions and lambdas etc. and it makes dealing with lists super fun. I want to be able to have this functionality on IEnumerables in C#. I think Matlab has a similarly concise syntax when operating on arrays/matrices.
Long story short, I want the following code (or similar) to work:
class Program
{
static List<MyClass> MyList = new List<MyClass>();
static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
MyList.Add(new MyClass());
MyList.MyMethod();
// should be exactly equivalent to:
MyList.Select(n => n.MyMethod());
}
}
class MyClass
{
public int MyMethod() { return 123; }
}
I'm aware this is possible on a case-by-case basis using extension methods:
public static IEnumerable<int> MyMethod(this IEnumerable<MyClass> lst)
{
return lst.Select(n => n.MyMethod());
}
But we'd have to create one extension method for every single method on every single type that you wanted this behaviour on.
Ideally this would be possible for all types and all methods and still be type-safe at compile time. I suspect I'm asking too much from the C# language here, but how would we do this or something similar in a as-generic-as-possible way?
Possible solutions:
Auto-generate extension methods for particular types. If we only intend to use this notation for a few types, we could just generate the extension methods once automatically. This would achieve the exact syntax and full type safety but generating code would be a pain.
A single extension method that returns a dynamic object built using reflection on the supplied type. The idea is that we'd use reflection to iterate through the type's methods and build up a dynamic object that would have all the methods like .MyMethod() that would behind the scenes call Select(...) on the IEnumerable. The syntax would end up being something like MyList.Selector().MyMethod(). But now we've lost the syntax and type safety. Clever, maybe. Useful, probably not.
Intercepting method calls? Is it possible to decide how to react to a method call at runtime? I don't know. Again you'd lose type safety.
The most simple solution is using dynamic objects. If you are willing to throw away type safety, you can make a IEnumerable type that behaves statically when needed and dynamically otherwise, here's a sample prototype:
public class DynamicIEnumerable<T> : DynamicObject, IEnumerable<T>
{
public IEnumerable<T> _enumerable;
public DynamicIEnumerable(IEnumerable<T> enumerable)
{
this._enumerable = enumerable;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
result = new DynamicIEnumerable<T>(_enumerable.Select(x => (T)typeof(T).InvokeMember(binder.Name, BindingFlags.InvokeMethod, null, x, null)));
return true;
}
public IEnumerator<T> GetEnumerator()
{
return _enumerable.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _enumerable.GetEnumerator();
}
}
In TryInvokeMember, the invoked member on IENumerable is applied on all items using reflection. The only constraints on this approach is that you have to return this in invoked method. Here's a sample of how to use this approach:
public class SomeClass
{
public int Value {get;set;}
public SomeClass(int value)
{
this.Value = x;
}
public SomeClass Plus10()
{
Value += 10;
return this;
}
}
static void Main()
{
dynamic d = new DynamicIEnumerable<X>(Enumerable.Range(0, 10).Select(x => new SomeClass(x)));
foreach (var res in d.Plus10().Plus10())
Console.WriteLine(res.Value);
}
how would we do this or something similar in a as-generic-as-possible way?
This isn't a pretty solution but it does work:
public class MyClass
{
public void MyMethod()
{
}
public void MyMethod2()
{
}
}
Extension Method:
public static class WeirdExtensions
{
public static IEnumerable<T> CallOnAll<T>(this IEnumerable<T> instance ,
Action<T> call)
{
foreach(var item in instance)
{
call(item);
}
return instance;
}
}
Usage (chaining/fluent):
var blah = new List<MyClass>();
blah.CallOnAll(b => b.MyMethod())
.CallOnAll(b => b.MyMethod2());
Notes
This isn't quite possible due to a the underlying assumption that you'd have to every single method on every single type. In jQuery/Html there is only one underlying type of an Html Element. All elements are exposed to the same methods (whether or not the type supports it). In jQuery, you can call $('head').hide() but it won't do anything visually, but because it is an element, it will be inline styled. If you need a new method, you do have a build one, but for only one type because there is only one type.
In contrast with C# you build your types (many many types) and they all have different methods (sure there could be overlap).

Get list of property names using interface method

I have two custom types Customer and Employee which implement the interface ITablefy. This interface has only one method, GetPropertyList which returns a list of strings of the property names of the object that implements it. I have a web service which looks like:
public string ReturnPropertyNames(ITablefy i)
{
List<string> propList = new List<string>();
TableFactory factory = new TableFactory();
ITablefy table = factory.CreateTable(i);
propList = table.GetPropertyList(table);
return propList[1];
}
so in this example the Factory creates a concrete type that implements ITablefy
I realized when I had a problem when both of my classes Customer and Employee implemented their GetPropertyList methods exactly the same:
//property list is a private member variable in each class
public List<string> GetPropertyList(ITablefy i)
{
TableFactory factory = new TableFactory();
ITablefy table = factory.CreateTable(i);
foreach (var propInfo in table.GetType().GetProperties())
{
propertyList.Add(propInfo.Name);
}
return propertyList;
}
Rather than copy and paste that code I'm looking for a better solution to what I have currently. If I only want certain types to use the GetPropertyList method how can I control that without having to copy and paste this same code? Harcoding the type to create in each class doesn't seem like a good solution to me. Employee and Customer don't logically make sense to use inheritance either. What's a proper solution for something like this?
factory:
public class TableFactory
{
public ITablefy CreateTable(ITablefy i)
{
if (i is Employee)
{
return new Employee();
}
else if (i is Customer)
{
return new Customer();
}
else
{
return null;
}
}
}
public static List<string> GetPropertyNames(this Object o)
{
List<string> names = new List<string>
foreach (PropertyInfo prop in o.GetType().GetProperties())
names.Add(prop.Name);
return names;
}
Now you can implement ITablefy in terms of any object.GetPropertyNames() using the extension method above.
There are a few questions that comes to my mind:
If It's so easy to do generically, why are you even using the interface?
Shouldn't you be checking properties for public accessors?
Shouldn't your interface be returning a more general type like IEnumerable<string> or ICollection<string>?
Wouldn't the interface be better designed to filter out property names that you don't want? That way you could assume all public properties are part of the set except those that aren't.
You make the interface be something like:
public interface IPropertyInfoFilterProvider {
public Func<PropertyInfo, bool> PropertyInfoSkipFilter { get; set; }
}
or
public interface IPropertyNameFilterProvider {
public Func<string, bool> PropertyNameSkipFilter { get; set; }
}
and then you can initialize the default to (prop) => false.
so now you can harvest the property names automagically and in one place and let implementations determine what gets taken and what doesn't and your harvesting code could use that filter in a linq where clause.
You could make it an extension method on ITablefy.
Or a static method on ITablefy

Is there any way to infer an Action type, or a full Action?

I find myself (too) often using a construct like the following:
class MyClass
{
public TypeA ObjectA;
public TypeB ObjectB;
public TypeC ObjectC;
public List<TypeD> ListOfObjectD = new List<TypeD>();
public void DoSmth()
{
return SomeConstruct(
/*...*/
new Setter<TypeA>(a => ObjectA = a), // these are the
new Setter<TypeB>(b => ObjectB = b), // things I'm trying
new Setter<TypeC>(c => ObjectC = c), // to make shorter
new Setter<TypeD>(d => ListOfObjectD.Add(d)),
/*...*/
);
}
}
class Setter<T>
{
public Action<T> Action;
public Setter(Action<T> action)
{
Action = action;
}
}
Is there any way for the Setter class to infer the type of the Action and create the standard (T obj) => Member = obj Action by only passing the Member in some way? I'm thinking of something like:
new Setter(ObjectA)
which of course is not valid syntax, but should give you an idea what I'm trying to achieve. I'm using this construct literally hundreds of time in my code, so the code
saved by this small change would be tremendous.
Edit: Added the TypeD example. The part
new Setter<TypeD>(d => ListOfObjectD.Add(d))
can be simplified to
new Setter<TypeD>(ListOfObjectD.Add)
which is awesome because it cuts from the redundant code. If only <TypeD> could also be inferred it would be perfect. I'm looking for something like this for the others.
#Lazarus - basically the purpose is to return setters, so other objects can set certain members of the class (or it can do other stuff defined in the Action) without accessing the class itself, only the Setter object. The full list of reasons is long and convoluted, but the structuring of the program works like a charm and I doubt needs changing (the example of course is simplified and doesn't really make sense as is).
Edit 2: I found a good way to simplify things for List's:
static class SetterHelper
{
public static Setter<T> GetSetter<T>(this List<T> list)
{
return new Setter<T>(list.Add);
}
}
Now I can just use this:
ListOfObjectD.GetSetter()
which works perfectly! why can't I do the same for T directly? I tried this:
static class SetterHelper
{
public static Setter<T> GetSetter<T>(this T item)
{
return new Setter<T>(t => item = t); // THIS DOESN'T SET THE PASSED MEMBER
}
}
Of course it won't work as intended because it will set item, but not the passed member. I tried adding ref as (ref this T item) but it won't compile :(... It would have been perfect.
Best I can offer you is the following syntax:
Setter.For( () => ObjectA );
using this helper class
static class Setter
{
public static Setter<T> For<T>(Expression<Func<T>> e)
{
ParameterExpression[] args = { Expression.Parameter(((e.Body as MemberExpression).Member as FieldInfo).FieldType) };
Action<T> s = Expression.Lambda<Action<T>>(Expression.Assign(e.Body, args[0]), args).Compile();
return new Setter<T>(s);
}
}

C# Generic overloading of List<T> : How would this be done?

The StringBuilder class allows you, in what I consider to be a very intuitive way, to chain method calls to .Append(), .AppendFormat() and some others like so:
StringBuilder sb = new StringBuilder();
sb.Append("first string")
.Append("second string);
The List class' .Add() method, on the other hand, returns void - so chaining calls doesn't work. This, in my opinion and the immortal words of Jayne Cobb "just don' make no kinda sense".
I admit that my understanding of Generics is very basic, but I would like to overload the .Add() method (and others) so that they return the original object, and allow chaining. Any and all assistance will be rewarded with further Firefly quotes.
If you want to keep the same name for the Add method, you could hide the method from the base class:
public class MyList<T> : List<T>
{
public new MyList<T> Add(T item)
{
base.Add(item);
return this;
}
}
However, this will only work if you're manipulating the list with a variable explicitly typed as MyList<T> (i.e. it won't work if your variable is declared as IList<T> for instance). So I think the solutions involving an extension method are better, even if that means changing the name of the method.
Although others have already posted solutions with extension methods, here's another one, that has the advantage of conserving the actual type of the collection:
public static class ExtensionMethods
{
public static TCollection Append<TCollection, TItem>(this TCollection collection, TItem item)
where TCollection : ICollection<TItem>
{
collection.Add(item);
return collection;
}
}
Use it like that:
var list = new List<string>();
list.Append("Hello").Append("World");
use can create extension method
public static class ListExtensions
{
public static List<T> AddItem<T>(this List<T> self, T item)
{
self.Add(item);
return self;
}
}
var l = new List<int>();
l.AddItem(1).AddItem(2);
EDIT
we can also make this method generic over collection parameter
public static class ListExtensions
{
public static TC AddItem<TC, T>(this TC self, T item)
where TC : ICollection<T>
{
self.Add(item);
return self;
}
}
var c1 = new Collection<int>();
c1.AddItem(1).AddItem(2);
var c2 = new List<int>();
c2.AddItem(10).AddItem(20);
EDIT 2:
Maybe someone will find this trick useful, it is possible to utilize nested object initializer and collection initializer for setting properties and adding values into existing instances.
using System;
using System.Collections.Generic;
using System.Linq;
struct I<T>
{
public readonly T V;
public I(T v)
{
V = v;
}
}
class Obj
{
public int A { get; set; }
public string B { get; set; }
public override string ToString()
{
return string.Format("A={0}, B={1}", A, B);
}
}
class Program
{
static void Main()
{
var list = new List<int> { 100 };
new I<List<int>>(list)
{
V = { 1, 2, 3, 4, 5, 6 }
};
Console.WriteLine(string.Join(" ", list.Select(x => x.ToString()).ToArray())); // 100 1 2 3 4 5 6
var obj = new Obj { A = 10, B = "!!!" };
Console.WriteLine(obj); // A=10, B=!!!
new I<Obj>(obj)
{
V = { B = "Changed!" }
};
Console.WriteLine(obj); // A=10, B=Changed!
}
}
public static IList<T> Anything-not-Add*<T>(this IList<T> list, T item)
{
list.Add(item);
return list;
}
* AddItem, Append, AppendList, etc. (see comments below)
The same idea came to my mind like other guys' too, independently:
public static TList Anything<TList, TItem>(this TList list, TItem item)
where TList : IList<TItem>
{
list.Add(item);
return list;
}
And Thomas is right: as far as IList<T> inherits ICollection<T> you should use ICollection.
Have an extension method off:
public static List<T> Append(this List<T> list, T item)
{
list.Add(item);
return self;
}
Note that we have to create it with a new name, as if an instance member matches the signature (the 'Add' you are already complaining about) then the extension method won't be called.
In all though, I'd recommend against this. While I like chaining myself, it's being rare in C# libraries means it's not as idiomatic as it is in other languages where it's more common (no technical reason for this, though some differences in how properties work encourages it a bit more in some other languages, just the way things are in terms of what is common). Because of this, the constructs it enables aren't as familiar in C# as elsewhere, and your code is more likely to be misread by another dev.
You could use an extension method with a different name:
public static T Put<T, U>(this T collection, U item) where T : ICollection<U> {
collection.Add(item);
return collection;
}
To create code like this:
var list = new List<int>();
list.Put(1).Put(2).Put(3);
To retain the name Add, however, you can have a method like this:
public static T Add<T, U>(this T collection, Func<U> itemProducer)
where T : ICollection<U> {
collection.Add(itemProducer());
return collection;
}
And create code like this:
list.Add(()=>1).Add(()=>2).Add(()=>3);
It doesn't look that good though.
Maybe if we change the type we can have a better syntax.
Given this class:
public class ListBuilder<T> {
IList<T> _list;
public ListBuilder(IList<T> list) {
_list = list;
}
public ListBuilder<T> Add(T item) {
_list.Add(item);
return this;
}
}
You can have this method:
public static ListBuilder<T> Edit<T>(this IList<T> list) {
return new ListBuilder<T>(list);
}
And use code like this:
list.Edit().Add(1).Add(2).Add(3);
I'm sure you won't appreciate this answer but there's a very good reason that List<>.Add() works this way. It is very fast, it needs to be to be competitive with an array and because it is such a low-level method. It is however just a hair too big to get inlined by the JIT optimizer. It cannot optimize the return statement you'd need to return the list reference.
Writing lst.Add(obj) in your code is for free, the lst reference is available in a CPU register.
A version of Add() that returns the reference makes the code almost 5% slower. It's a lot worse for the proposed extension method, there an entire extra stack frame involved.
I like the extension approach that others have mentioned as that seems to answer the question well (although you would have to give it a different method signature than the existing Add()). Also, it does seem like there's some inconsistency about object returns on calls like this (I thought it was a mutability issue, but the stringbuilder is mutable isn't it?), so you raise an interesting question.
I'm curious, though, if the AddRange method would not work as an out-of-the-box solution? Is there a particular reason you want to chain the commands instead of passing everything in as a an array?
Would do something like this not accomplish what you need?
List<string> list = new List<string>();
list.AddRange(new string[]{
"first string",
"second string",
});

Categories

Resources