Object Initializer for object collections - c#

I am wanting to find out if there is a way to initialize a List<T> where T is an object much like a simple collection gets initialized?
Simple Collection Initializer:
List<int> digits = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Object Collection Initilizer:
List<ChildObject> childObjects = new List<ChildObject>
{
new ChildObject(){ Name = "Sylvester", Age=8 },
new ChildObject(){ Name = "Whiskers", Age=2 },
new ChildObject(){ Name = "Sasha", Age=14 }
};
The question is, how and if you can do something like this?
List<ChildObject> childObjects = new List<ChildObject>
{
{ "Sylvester", 8} , {"Whiskers", 2}, {"Sasha", 14}
};

If you look at the docs for collection initializers, it's all about the collection's Add method. Just subclass the closed generic List over your type and make an Add method with the naked parameters. Like
public class MyColl : List<ChildObject>
{
public void Add(string s1, int a1, int a2)
{
base.Add(new ChildObject(s1, a1, a2));
}
}
public class ChildObject
{
public ChildObject(string s1, int a1, int a2)
{
//...
}
}
Then calling it looks like:
static void Main(string[] args)
{
MyColl x = new MyColl
{
{"boo", 2, 4},
{"mang", 3, 5},
};
}

The best you can probably do is something like this:
public class MyListOfChildObjects : List<ChildObject>
{
public void Add( string name, int age )
{
Add ( new ChildObject { Name = name, Age = age } );
}
}
var childObjects = new MyListOfChildObjects
{
{ "Sylvester", 8 } , { "Whiskers", 2 }, { "Sasha", 14 }
};
You could make it more generic, but how would you know which arguments should be bound to each property?
public class MyList<T> : List<T>
{
public void Add( params object[] arguments )
{
// what order should I bind the values to?
}
}
var childObjects = new MyList<ChildObject>
{
{ "Sylvester", 8 } , { "Whiskers", 2 }, { "Sasha", 14 }
};

You can get close by creating your own collection which extends List<ChildObject> and provide your own add method:
public class ChildObjectCollection : List<ChildObject>
{
public void Add(string name, int age)
{
this.Add(new ChildObject(name, age));
}
}
You can then initialise it like this:
var childObjects = new ChildObjectCollection
{
{ "Sylvester", 8} , {"Whiskers", 2}, {"Sasha", 1 }
};

You can't do this without creating your own class derived from List<ChildObject> as per Lee's answer. It's unfortunate that extension methods aren't considered for collection initalizers, otherwise this would work:
// This doesn't work, but it would if collection initializers checked
// extension methods.
using System;
using System.Collections.Generic;
public class ChildObject
{
public string Name { get; set; }
public int Age { get; set; }
}
public static class Extensions
{
public static void Add(this List<ChildObject> children,
string name, int age)
{
children.Add(new ChildObject { Name = name, Age = age });
}
}
class Test
{
static void Main(string[] args)
{
List<ChildObject> children = new List<ChildObject>
{
{ "Sylvester", 8 },
{ "Whiskers", 2 },
{ "Sasha", 14 }
};
}
}

The closest you can get to that is to create a parameterized constructor on your class that accepts those arguments. That won't get you all the way, but you can at least do this:
List<ChildObject> childObjects = new List<ChildObject>
{
new ChildObject("Sylvester", 8) ,
new ChildObject("Whiskers", 2),
new ChildObject("Sasha", 14)
};

Related

Syntactic sugar, simplify list initialisation like dictionary

To initialize a List<T> you have to use individual type initializer for each element - something like this:
List<Cat> cats = new List<Cat>
{
new Cat { Name = "Sylvester", Age = 8 },
new Cat { Name = "Whiskers", Age = 2 },
new Cat { Name = "Sasha", Age = 14 }
};
But for Dictionary you don't have to use the KeyValuePair initializer:
var numbers = new Dictionary<int, string>
{
{ 19, "nineteen" },
{ 23, "twenty-three" },
{ 42, "forty-two" }
};
Dictionary seems to be using the public void Add(TKey key, TValue value), and list also has a method public void Add(T item).
Is it possible to use a simplified initialisation for List<T> without individual initializers? Is it possible to List<T> to do it?
The only way you can do that is if you create your own list type with a Add(string name, int age) method.
public class Cat
{
public string Name { get; set; }
public int Age { get; set; }
}
public class CatList : List<Cat>
{
public void Add(string name, int age) => Add(new Cat { Name = name, Age = age });
}
Then you can run this code
var list = new CatList
{
{ "Sylvester", 8 },
{ "Whiskers", 2 },
{ "Sasha", 14 }
};
Console.WriteLine(string.Join(";", list.Select(c => $"{c.Name} is {c.Age}")));
But honestly I'm not sure it's worth it as you'd need to create custom collection types for each underlying type you want to store to be able to do this.
Another option is to initialize a list of value tuples and then translate it.
var list = new List<(string Name, int Age)>
{
( "Sylvester", 8 ),
( "Whiskers", 2 ),
( "Sasha", 14 )
}
.Select(x => new Cat { Name = x.Name, Age = x.Age })
.ToList();
Console.WriteLine(string.Join(";", list.Select(c => $"{c.Name} is {c.Age}")));
In C# 6 you can also use Extension Add methods in collection initializers so that you don't need to create own collection type:
public static class CatListExtensions
{
public static void Add(this List<Cat> list, string name, int age)
{
list.Add(new Cat {Name = name, Age = age});
}
}
After adding such extension method you will be able to use it in collection initializer:
List<Cat> list = new List<Cat>
{
{"Sylvester", 8},
{"Whiskers", 2},
{"Sasha", 14}
};
Collection initializers for List and Dicitionary use internally Add method, for List it is public void Add (T item); and for dictionary it is public void Add (TKey key, TValue value);, so Dictionary collection initializer does not actually construct KeyValuePair to pass it to the Add method and this code:
var numbers = new Dictionary<int, string>
{
{ 19, "nineteen" },
{ 23, "twenty-three" },
{ 42, "forty-two" }
};
Is translated into something like this:
Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(19, "nineteen");
dictionary.Add(23, "twenty-three");
dictionary.Add(42, "forty-two");
You should be able to implement your own collection of Cat's which will have Add method with all needed parameters so you can initialize it without passing the type name.

Creating a generic interface for a class when the generic type depends on where its getting called from

I am attempting to create a generic interface that can be implemented by a class who needs to be able to return EITHER a List of type Class1 OR Class2. I have not been able to get this working because I need to pass in the IRules generic type and if I pass in ClassAbstract I run into the problem below(a very short generic example of what I am really dealing with) where one of the properties is only one of the derived types and not on the base type.
I am not sure how I can get this working the way I want to--basically in that section I can check the type of list and then specify what to do but the issue is that because I am passing in ClassAbstract as the generic parameter this isn't going to work either...is there a way to get this working properly without having to specify the interface type because I don't actually know whether it will be a List of Class1 or a List of Class2 and its based on where it is getting called from? I obviously could duplicate the code and just use once method for each class type but its a lot of code and I don't think this should be that hard to do what I want to do but maybe I am wrong...
public interface IRules<T> {
List<T>GetAdditionalPropRules(List<T> list1);
List<T>SetAdditionalPropRules(List<T> list1);
}
public ClassAbstract {
public string NAME {get;set;}
public string AGE {get;set;}
}
public class Class1: ClassAbstract {
public string JOB {get;set;}
}
public class Class2: ClassAbstract {
}
public class Rules MyProperties: IRules<ClassAbstract>{ **<--- I Want this to be able to accept either Class1 or Class2**
public List<ClassAbstract> SetAdditionalPropRules(List<ClassAbstract> myList) {
foreach(dynamic item in myList) {
if(item.NAME == "Joe") {
myList.Add(new ClassAbstract {
AGE = 30,
JOB = "Tester" **<--- ISSUE RIGHT HERE -- ClassAbstract Does not have property JOB**
}
}
}
}
}
Is that can help you?
using System;
using System.Linq;
using System.Collections.Generic;
namespace ConsoleApp
{
static partial class Program
{
static void Main(string[] args)
{
Test();
Console.WriteLine();
Console.WriteLine("End.");
Console.ReadKey();
}
static void Test()
{
var rules = new RulesMyProperties();
var list = new List<ClassAbstract>();
list.Add(new Class1 { NAME = "Joe", AGE = 20 });
list.Add(new Class2 { NAME = "Joe", AGE = 25 });
list.Add(new Class1 { NAME = "John", AGE = 30 });
list.Add(new Class2 { NAME = "John", AGE = 35 });
Action print = () =>
{
foreach ( var item in list )
{
Console.Write($"{item.NAME} / {item.GetType().Name} : {item.AGE}");
if ( item is Class1 )
Console.Write($" ({((Class1)item).JOB})");
Console.WriteLine();
}
};
print();
rules.SetAdditionalPropRules(list);
Console.WriteLine();
print();
}
}
public class RulesMyProperties : IRules<ClassAbstract>
{
public List<ClassAbstract> SetAdditionalPropRules(List<ClassAbstract> myList)
{
foreach ( var item in myList.ToList() )
{
if ( item != null )
if ( item.NAME == "Joe" )
{
if ( item is Class1 )
{
( item as Class1 ).AGE = 30;
( item as Class1 ).JOB = "Tester";
}
else
{
myList.Remove(item);
myList.Add(new Class1
{
NAME = "Joe",
AGE = 30,
JOB = "Tester"
});
}
break;
}
}
return myList;
}
public List<ClassAbstract> GetAdditionalPropRules(List<ClassAbstract> list1)
{
throw new NotImplementedException();
}
}
public interface IRules<T>
{
List<T> GetAdditionalPropRules(List<T> list1);
List<T> SetAdditionalPropRules(List<T> list1);
}
public class ClassAbstract
{
public string NAME { get; set; }
public int AGE { get; set; }
}
public class Class1 : ClassAbstract
{
public string JOB { get; set; }
}
public class Class2 : ClassAbstract
{
}
}
Output:
Joe / Class1 : 20 ()
Joe / Class2 : 25
John / Class1 : 30 ()
John / Class2 : 35
Joe / Class1 : 30 (Tester)
Joe / Class2 : 25
John / Class1 : 30 ()
John / Class2 : 35
perhaps, like this? - if you base your Class1 and Class2 on some interface:
interface IClassAbsract
{
string Name { get; set; }
string Age { get; set; }
}
public class Class1: IClassAbsract
{
public string Name { get; set; }
public string Age { get; set; }
}
public class Class2 : IClassAbsract
{
public string Name { get; set; }
public string Age { get; set; }
}
public class ListRule
{
public List<IClassAbsract> List { get; set; } = new List<IClassAbsract>();
}
then, later, those can be used like this:
...
...
//populate list with testing instances
var list = new ListRule();
var c1 = new Class1() { Name = "Class #1", Age = "11" };
list.List.Add(c1);
var c2 = new Class2() { Name = "Class #2", Age = "22" };
list.List.Add(c2);
...
//then, get only certain types, and populate second list "myList": for example, pull only of type Class1:
public void Test2(List<IClassAbsract> list)
{
if (list == null || !list.Any())
{
throw new System.ArgumentNullException("empty");
}
//pull only of type Class1:
List<IClassAbsract> myList = new List<IClassAbsract>();
myList.AddRange(list
.Where(e => e is Class1)
.Select(e => new Class1() { Age = e.Age, Name = "Joe" })
.ToList()
);
}

C# - How can I make one array of different classes that share common properties?

I have a C# class called PersonActivity. This holds a unique Id (int), a PersonId (int), and an ActivityType (string).
I have another class HighlightedActivity that inherits from PersonActivity. What I need to do is make an array HighlightedActivity[] called "activities", which I've done. My question is how can I make this one array, but with certain additional properties based on the ActivityType?
My intention is to loop through "activities" of HighlightedActivity type, then set additional properties that are based on the ActivityType. Activity Types are things like Books that have an ISBN number, while Journals have a Volume and Issue number, and Grants have an Amount. They all have Id, PersonId, and ActivityType from the PersonActivity class. I'm not sure what HighlightedActivity class should look like so that I can put all these items in the same list.
Array "activities" should look like:
[0] {Id = 2, PersonId = 5, ActivityType = "Book", ISBN = "13239382"}
[1] {Id = 3, PersonId = 5, ActivityType = "Journal", Volume = 5, Issue = 124}
[2] {Id = 4, PersonId = 5, ActivityType = "Journal", Volume = 8, Issue = 201}
[3] {Id = 5, PersonId = 5, ActivityType = "Journal", Volume = 8, Issue = 202}
[4] {Id = 6, PersonId = 5, ActivityType = "Grant", Amount = 444.00}
You can create base activity class (consider also to make activities read-only Value objects if you are not going to change them after creation):
public abstract class Activity
{
public int Id { get; set; }
public int PersonId { get; set; }
public string ActivityType { get; private set; } // consider to use enum
public Activity(string activityType)
{
ActivityType = activityType;
}
}
And then create custom activity classes which inherit this base class:
public class Book : Activity
{
public Book() : base("Book") { }
public string ISBN { get; set; }
}
public class Journal : Activity
{
public Journal() : base("Journal") { }
public int Volume { get; set; }
public int Issue { get; set; }
}
And keep list of base type activities:
var activities = new List<Activity> {
new Book { Id = 2, PersonId = 5, ISBN = "13239382" },
new Journal { Id = 3, PersonId = 5, Volume = 5, Issue = 124 },
new Journal { Id = 4, PersonId = 5, Volume = 8, Issue = 201 },
new Journal { Id = 5, PersonId = 5, Volume = 8, Issue = 202 }
// etc
};
Then you can cast each activity to appropriate type and retrieve its properties (sample with C# 7 pattern matching):
foreach(var activity in activities)
{
switch(activity)
{
case Book book:
/* use book here */
break;
case Journal journal:
/* use journal here */
break;
default:
/* handle unknown activity */
break;
}
}
You can also switch by activity type and cast activity to appropriate class.
You can create a base activity class and inherit your other objects from that. The base class will have an activity type which can be used to track the type of activity.
Define this as an enum:
public enum ActivityType
{
Book,
Journal,
Grant
}
Your base class will hold the common properties. It will also have constructors to create derived classes by activity type and from an array. Since we will have an array based constructor, we will validate the array length and add protected members that can be used to convert array objects to their correct types.
public abstract class Activity
{
public int Id { get; set; }
public int PersonId { get; set; }
public ActivityType ActivityType { get; private set; } // consider to use enum
public Activity(ActivityType activityType)
{
ActivityType = activityType;
}
public Activity(object[] values)
{
if (values.Length < 4)
throw new ArgumentException();
this.Id = getInt(values[0]);
this.PersonId = getInt(values[1]);
this.ActivityType = getActivityType(values[2]);
}
protected int getInt(object value)
{
if (!(value is int))
{
throw new ArgumentException();
}
return (int)value;
}
protected string getString(object value)
{
if (!(value is string))
{
throw new ArgumentException();
}
return (string)value;
}
protected decimal getDecimal(object value)
{
if (!(value is decimal))
{
throw new ArgumentException();
}
return (decimal)value;
}
protected ActivityType getActivityType(object value)
{
ActivityType result;
if(value is string)
{
if (!Enum.TryParse((string)value, out result))
{
throw new ArgumentException();
}
}
else if(value is ActivityType)
{
result = (ActivityType)value;
}
else
{
throw new ArgumentException();
}
return result;
}
}
We now define the derived classes which will call base constructors to set base properties as needed. For the array constructors, validate the array length and use base methods to covert array objects to there correct types.
public class Book : Activity
{
public Book() : base(ActivityType.Book) { }
public Book(object[] values) : base(values)
{
if (values.Length != 4) throw new ArgumentException();
this.ISBN = getString(values[3]);
}
public string ISBN { get; set; }
}
public class Journal : Activity
{
public Journal() : base(ActivityType.Journal) { }
public Journal(object[] values) : base(values)
{
if (values.Length != 5) throw new ArgumentException();
this.Volume = getInt(values[3]);
this.Issue = getInt(values[4]);
}
public int Volume { get; set; }
public int Issue { get; set; }
}
public class Grant : Activity
{
public Grant() : base(ActivityType.Grant) { }
public Grant(object[] values) : base(values)
{
if (values.Length != 4) throw new ArgumentException();
this.Volume = getDecimal(values[3]);
}
public decimal Volume { get; set; }
}
Finally, we will create a class that uses the factory pattern to create activities from an array or a list of activities from an array of arrays. The factory will also have a method to test the data you defined above.
public class ActivityFactory
{
public static List<Activity> GetActivities(object[][] values)
{
List<Activity> result = new List<Activity>();
for (int i = 0; i < values.Length; i++)
{
result.Add(MakeActivity(values[i]));
}
return result;
}
static Activity MakeActivity(object[] values)
{
Activity result = null;
switch (values[2].ToString())
{
case "Book":
result = new Book(values);
break;
case "Journal":
result = new Journal(values);
break;
case "Grant":
result = new Grant(values);
break;
default:
throw new ArgumentException("Invalid activity " + values[2].ToString());
}
return result;
}
public static void RunTest()
{
object[][] values = new object[][] {
new object[] { 2, 5, "Book", "13239382"},
new object[] { 3, 5, "Journal", 5, 124},
new object[] { 4, 5, "Journal", 8, 201},
new object[] { 5, 5, "Journal", 8, 202},
new object[] { 6, 5, "Grant", 444.00m}
};
List<Activity> activities = GetActivities(values);
}
}

Generic List that holds a generic list

I was wondering if there was a method in which I can hold a generic list that can hold a generic list.
My issue is that I have a list that can hold either LIST A or LIST B or LIST C.
I figured out how to do this with Data types but I want this list to be able to hold classes that I create.
For example:
List<T> listA = new List<T>();
Where T is ObjectX
listA.Add(new list<Y> { new List<U>() { new List<T>() } } );
Where Y is ObjectY<br>
Where U is ObjectU
etc.
EDIT:
Let me put it into context.
I have a list of Objects called Suites
Each Suite can have a list of CaseObjects OR a list of CaseHolderObjects.
Each CaseHolder can hold a list of CaseObjects
Each Case can hold a list of ActionObjects
I think this is what you want:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace TestList
{
public class Program
{
public static void Main(string[] args)
{
//Use this syntax for a list of list of classes
List<List<Test>> test = new List<List<Test>>();
}
}
//This class is just for example.
class Test
{
//Your class code here
}
}
This is what you wanted, a list that holds any other type of list ^^
class Program
{
static void Main(string[] args)
{
Person p1 = new Person(1, "Mario");
Person p2 = new Person(2, "Franco");
Dog d1 = new Dog(1, "Fuffy");
Dog d2 = new Dog(2, "Chop");
List<Person> listP = new List<Person>();
listP.Add(p1);
listP.Add(p2);
List<Dog> listD = new List<Dog>();
listD.Add(d1);
listD.Add(d2);
List<Object> listO = new List<Object>();
listO.Add(listP);
listO.Add(listD);
}
public class Person
{
public Person(int id, string name)
{
this.id = id;
this.name = name;
}
public int id { get; set; }
public string name { get; set; }
}
public class Dog
{
public Dog(int id, string name)
{
this.id = id;
this.name = name;
}
public int id { get; set; }
public string name { get; set; }
}
}
I solved the issue. The classes in question I had them implement an empty interface. I then created a single property.
List<List<Interfaces.IMetaData>> myList = new List<List<Interfaces.IMetaData>>();
myList.Add(new List<Interfaces.IMetaData>() { new SuiteObject() { } });
myList.Add(new List<Interfaces.IMetaData>() { new CaseHolderObject() { } });
myList.Add(new List<Interfaces.IMetaData>() { new CaseObject() { } });
myList.Add(new List<Interfaces.IMetaData>() { new ActionObject() { } });
You don't need generic collection if you want to store different class in it. Try to use ArrayList (System.Collections namespace). You can add to it any object (of cource cost of performace);
For example:
ArrayList listA = new ArrayList() { 1, true, "string" };
ArrayList ListB = new ArrayList() { 2, false };
ArrayList ListC = new ArrayList() { 3, "string3" };
ListB.Add(ListC);
listA.Add(ListB);

Using collection initializer syntax on custom types?

I have a large static list which is basically a lookup table, so I initialise the table in code.
private class MyClass
{
private class LookupItem
{
public int Param1 { get; set; }
public int Param2 { get; set; }
public float Param2 { get; set; }
public float Param4 { get; set; }
}
private static List<LookupItem> _lookupTable = new List<LookupItem>()
{
new LookupItem() { Param1 = 1, Param2 = 2, Param3 = 3 Param4 = 4 },
new LookupItem() { Param1 = 5, Param2 = 6, Param3 = 7 Param4 = 8 },
//etc
}
}
The real LookupItem has many more properties, so I added a constructor to allow for a more compact initialisation format:
private class MyClass
{
private class LookupItem
{
public int Param1 { get; set; }
public int Param2 { get; set; }
public float Param2 { get; set; }
public float Param4 { get; set; }
public LookupItem(int param1, int param2, float param3, float param4)
{
Param1 = param1;
Param2 = param2;
Param3 = param3;
Param4 = param4;
}
}
private static List<LookupItem> _lookupTable = new List<LookupItem>()
{
new LookupItem(1, 2, 3, 4),
new LookupItem(5, 6, 7, 8),
//etc
}
}
What I'd really like to do is use the collection initialiser format for the object itself so I can get rid of the new LookupItem() on every line. eg:
private static List<LookupItem> _lookupTable = new List<LookupItem>()
{
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
//etc
}
Is this possible? I like to think it is because the KeyValuePair's of a Dictionary<> can be initialised in this way.
MSDN States:
Collection initializers let you specify one or more element
intializers when you initialize a collection class that implements
IEnumerable. The element initializers can be a simple value, an
expression or an object initializer. By using a collection initializer
you do not have to specify multiple calls to the Add method of the
class in your source code; the compiler adds the calls.
Does this mean I need to implement IEnumerable on my LookupItem class and return each parameter? My class isn't a collection class though.
I think you need to make a custom collection instead of List. Call it LookupItemTable, for example. Give that collection an Add(int, int, float, float) method and have it implement IEnumerable. For example:
class LookupItem
{
public int a;
public int b;
public float c;
public float d;
}
class LookupItemTable : List<LookupItem>
{
public void Add(int a, int b, float c, float d)
{
LookupItem item = new LookupItem();
item.a = a;
item.b = b;
item.c = c;
item.d = d;
Add(item);
}
}
private static LookupItemTable _lookupTable = new LookupItemTable {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 }
};
I've now tried the above code and it seems to work for me.
Quick fix : Make your own List type with an Add overload that takes multiple arguments:
class LookupList : List<LookupItem> {
public void Add(int Param1, int Param2, ... sometype ParamX) {
this.Add(new LookupItem() { Param1 = Param1, Param2 = Param2, ... ParamX = ParamX });
}
}
Now works exactly as you want:
private static LookupList _lookupTable = new LookupList() {
{1,2,3,4},
{2,7,6,3}
};
More fundamental answer:
You're mixing up object initializers and collection initializers. Put simply:
Object initializers are a syntactic trick that, in the background call the property set methods for each named property with the value specified.
Collection initializers are a syntactic trick that, in the background:
For an Array type: Fill the array with the items
For any other type, which must implement IEnumerable: Call the Add method for each sub-bracketed set.
That is all there is to it. Consider for example the following hack:
public class Hack : IEnumerable {
public int LuckyNumber { get; set; }
public double Total { get; private set; }
public void Add(string message, int operand1, double operand2, double operand3) {
Console.WriteLine(message);
this.Total += operand1 * operand2 - operand3;
}
public IEnumerator GetEnumerator() { throw new NotImplementedException(); }
}
class Program {
static void Main(string[] args) {
Hack h1 = new Hack() {
{ "Hello", 1, 3, 2},
{ "World", 2, 7, 2.9}
};
Console.WriteLine(h1.Total);
Hack h2 = new Hack() { LuckyNumber = 42 };
Console.WriteLine(h2.LuckyNumber);
}
}
You should never do this in a real program, but I hope examining this example and the results, especially if you debug step through it, will help you understand the initializers clearly and choose a good solution for your current scenario.
You're trying to use a collection initializer on the list itself, not on your type:
// Note the "new List<...>" part - that specifies what type the collection
// initializer looks at...
private static List<LookupItem> _lookupTable = new List<LookupItem>()
{
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
}
So it's looking for an Add method with four parameters on List<T>, and that doesn't exist.
You would have to implement your own collection class to use a custom collection initializer. While you're using List<T>, you're stuck with the constructor calls you've got.
Rather than obscure the intent of List with a custom class deriving from List<LookupItem>, add a simple extension that calls the required constructor:
public static class LookupItemListExtensions
{
public static void Add(this List<LookupItem> lookupItemList, int param1, int param2, float param3, float param4)
{
lookupItemList.Add(new LookupItem(param1, param2, param3, param4));
}
}
Note that you're trading clarity for brevity, so use at your own risk. Using "new ListItem" lets you F12 directly to the constructor; this extension does not (nor will it ever likely be obvious to other developers).
Does this mean I need to implement IEnumerable on my LookupItem class
and return each parameter? My class isn't a collection class though.
No, it means that List<LookupItem> implements IEnumerable, which is why you can write
private static List<LookupItem> _lookupTable = new List<LookupItem>()
{
new LookupItem(1, 2, 3, 4),
new LookupItem(5, 6, 7, 8),
//etc
}
It also means that if your LookupItem was a collection that implemented IEnumerable, you could have written:
private static List<LookupItem> _lookupTable = new List<LookupItem>()
{
new LookupItem { new Item(), new Item() },
new LookupItem { new Item(), new Item() }
}

Categories

Resources