I have got a method which returns five arrays of different dimensions:
public static (string[],string[],string[,],string[,],string[,]) deserializeobject(string filename)
{
return (Auftraggeber, Aufstellungsort, Anlagen, Vorgang_rückgemeldet, Vorgang_zukünftig);
}
How do I correctly call this method to further work with the arrays?
I would stronly suggest to create a class for that, in particular as the method is public and thus could be used in multiple contexts. That makes it far easier for users of your API to determine the meaning of every returned member.
Your individual members seem to have a descene tmeaning anyway, so why throw it away and return a collection of namesless paramaters?
class MyObject
{
public string[] Auftraggeber { get; set; }
public string[] Aufstellungsort { get; set; }
public string[] Anlagen { get; set; }
public string[] Vorgang_rückgemeldet { get; set; }
public string[] Vorgang_zukünftig { get; set; }
}
And:
public static MyObject Deserialize(string fileName)
{
return new MyObject { AuftragGeber = ... };
}
Now users of your method can easily determine what the parameters mean:
var o = deserialize(myFile);
DoSomething(o.Aufstellungsort);
which is far easier to read than this:
var o DoSomething(myFile);
DoSomething(o.Item2);
isn´t it? Apart from this it limits typos. In the second case users can easily type Item2 when they actually ment Item1, which may cause headache when debugging. With a descent name for every member those typos are far more unlikely.
First the response to your question:
Given:
public static (string[], string[], string[,], string[,], string[,]) deserializeobject(string filename)
{
// Some value that will be returned... Just doing a test here
return default((string[], string[], string[,], string[,], string[,]));
}
You can:
// Using var
var des1 = deserializeobject("foo.bin");
Console.WriteLine($"Lengths: {des1.Item1.Length}, {des1.Item2.Length}, {des1.Item3.Length}, {des1.Item4.Length}, {des1.Item5.Length}");
// Legal, but too much verbose
(string[], string[], string[,], string[,], string[,]) des2 = deserializeobject("foo.bin");
// Legal too, because in truth the ValueTuple<> struct is used
ValueTuple<string[], string[], string[,], string[,], string[,]> des3 = deserializeobject("foo.bin");
Now, the problem here is that, as I've written in a comment, you need a special type of hate for your coworkers to do this. Why? Because if I ask you, what is Item4, can you give me a response? No :-) Fortunately there are two alternatives: creating a full class/struct to contain the return value or using named tuples. I'm quite against creating a class that will be used only by a single method, so I'll show you the named tuples way.
Using named tuples you can:
public static (string[] Auftraggeber, string[] Aufstellungsort, string[,] Anlagen, string[,] VorgangRückgemeldet, string[,] VorgangZukünftig) deserializeobject2(string filename)
{
return default((string[], string[], string[,], string[,], string[,]));
}
Then you can:
// Using var, with named arguments:
var des4 = deserializeobject2("foo.bin");
Console.WriteLine($"Lengths: {des4.Auftraggeber.Length}, {des4.Aufstellungsort.Length}, {des4.Anlagen.Length}, {des4.VorgangRückgemeldet.Length}, {des4.VorgangZukünftig.Length}");
See? The name of the items (arrays) returned by your method is maintained...
Note that named tuples are a sleight of hand. There are no named tuples underside. There are only ValueTuple<> that are "annotated" with the name of the properties that you want.
This is legal:
ValueTuple<string[], string[], string[,], string[,], string[,]> des5 = des4;
Full example to the question in comment:
public static (string[] Auftraggeber, string[] Aufstellungsort, string[,] Anlagen, string[,] VorgangRückgemeldet, string[,] VorgangZukünftig) deserializeobject2(string filename)
{
// Define/create/fill the arrays
var auftraggeber = new string[10];
var aufstellungsort = new string[10];
var anlagen = new string[10, 10];
var vorgangRückgemeldet = new string[10, 10];
var vorgangZukünftig = new string[10, 10];
// Return the arrays
return (auftraggeber, aufstellungsort, anlagen, vorgangRückgemeldet, vorgangZukünftig);
}
use Tuple<> like below code :
public Tuple<int[], int[]> GetMultipleValue(string name)
{
int[] a = new int[]{1,2,3,4}
int[] b = new int[]{5,6,7,8}
return Tuple.Create(a,b);
}
Related
I'm instantiating an object with properties coming from a IEnumerable. The straightforward way is
IEnumerable<string> source = ...
var instance = new X(
source.First(),
source.Skip(1).First(),
source.Skip(2).First(),
...
);
Where X is a class with a constructor that takes a number of parameters.
This works, but it feels like this is a common scenario (for example fetching data using a generic storage layer and instantiating a specific record type) that there should be a cleaner way.
I considered making a list using a .ToList() and then access the properties using the indexer, but that evaluates the whole Enumerable which I don't feel is warranted here.
Is there a cleaner approach? I was imagining an Enumerator approach that would allow me to .MoveNext() & .Current approach, that would allow me O(1) access and no unnecessary allocations -- but with some syntax sugar to make that pretty
It looks like you're trying to take the first N values from the series, for some value of N.
If the X(...) takes a params string[], then you can just use source.Take(N).ToArray(); since we'll be building the array anyway, this has no particular additional overhead.
If the X(...) takes N separate string parameters, then you do need to unroll it, but iterating the sequence multiple times is awkward. It may be ugly, but I'd probably use something custom here:
string a, b, c;
using (IEnumerator<string> iter = source.GetEnumerator())
{
a = iter.Next();
b = iter.Next();
c = iter.Next();
}
return new X(a, b, c);
static class Utils
{
public static T Next<T>(this IEnumerator<T> source)
{
if (!source.MoveNext()) Throw();
return source.Current;
static void Throw() => throw new InvalidOperationException("Missing element from sequence");
}
}
You could also move the constructor inside the using, if you don't mind extending the sequence living a little longer (into the constructor invoke):
using IEnumerator<string> iter = source.GetEnumerator();
return new X(iter.Next(), iter.Next(), iter.Next());
You can pass parameters via activator.createinstanc<T>
See here: https://learn.microsoft.com/en-us/dotnet/api/system.activator.createinstance?redirectedfrom=MSDN&view=net-7.0#System_Activator_CreateInstance_System_Type_System_Object___
Try this:
using System;
using System.Collections.Generic;
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public Person(string firstName, string lastName, int age)
{
FirstName = firstName;
LastName = lastName;
Age = age;
}
}
class Program
{
static void Main(string[] args)
{
List<object> constructorArgs = new List<object>() { "David", "Božjak", 30 };
Person p = (Person)Activator.CreateInstance(typeof(Person), constructorArgs.ToArray());
Console.WriteLine($"{p.FirstName} {p.LastName} is {p.Age} years old.");
}
}
I have below class
public class HydronicEquipment
{
public List<LibraryHydronicEquipment> Source { get; set; }
public List<LibraryHydronicEquipment> Distribution { get; set; }
public List<LibraryHydronicEquipment> Terminals { get; set; }
}
and then i have the below class for "libraryHydronicEquipment"
public class LibraryHydronicEquipment : IEquipmentRedundancy
{
public string Name { get; set; }
public RedundancyStatus RedundancyStatus { get; set; }
public EquipmentRedundancy EquipmentRedundancy { get; set; }
}
I am trying to concatenate the list of "LibraryHydronicEquipment" objects available from all three properties (i.e) from source, distribution and terminal and General concatenate method will looks like as this below
var source = hydronicEquipment.Source;
var distribution = hydronicEquipment.Distribution;
var teriminals = hydronicEquipment.Terminals;
Source.Concat(Distribution).Concat(Terminals)
I am trying to achieve the same using reflection and the code looks like as below
foreach (var (systemName, hydronicEquipment) in hydronicSystemEquipment)
{
bool isFirstSystem = true;
var equipmentList = new List<string> { "Source", "Distribution", "Terminals" };
var redundancyequipmentList = GetRedundancyEquipment(hydronicEquipment, equipmentList);
}
and the method GetRedundancyEquipment is looks like below
private static IEnumerable<IEquipmentRedundancy> GetRedundancyEquipment(HydronicEquipment hydronicEquipment, List<string> equipmentList)
{
IEnumerable<IEquipmentRedundancy> equipmentRedundancies = new List<IEquipmentRedundancy>();
dynamic equipmentResults = null;
foreach(var equipment in equipmentList)
{
var componentList = hydronicEquipment.GetType().GetProperty(equipment).GetValue(hydronicEquipment, null) as IEnumerable<IEquipmentRedundancy>;
equipmentResults = equipmentRedundancies.Concat(componentList);
}
return equipmentResults;
}
The problem here is even though i have Source is having list of objects and Distribution is having list of objects, the equipmentResults is giving only one object instead of list of concatenated objects.
I am trying to return the IEnumerable<IEquipmentRedundancy> at the end using reflection method but it seems not working with the above code.
Could any one please let me know how can i achieve this, Many thanks in advance.
GetRedundancyEquipment should preserve your values instead of reassign the reference with each iteration. Here's the fixed version:
private static IEnumerable<IEquipmentRedundancy> GetRedundancyEquipment(HydronicEquipment hydronicEquipment, List<string> equipmentList)
{
IEnumerable<IEquipmentRedundancy> equipmentRedundancies = new List<IEquipmentRedundancy>();
var equipmentResults = new List<IEquipmentRedundancy>();
foreach (var equipment in equipmentList)
{
var componentList = hydronicEquipment.GetType().GetProperty(equipment).GetValue(hydronicEquipment, null) as IEnumerable<IEquipmentRedundancy>;
equipmentResults.AddRange(equipmentRedundancies.Concat(componentList));
}
return equipmentResults;
}
If we look at what you're doing in GetRedundancyEquipment() it becomes clear.
First you create equipmentRedundancies = new List<IEquipmentRedundancy>();
Then you never modify equipmentRedundancies - e.g. via Add(). It remains an empty list until it goes out of scope and is garbage collected.
In a loop you then repeatedly make this assignment equipmentResults = equipmentRedundancies.Concat(componentList);
That is to say: Assign to equipmentResults the concatenation of componentList to equipmentRedundancies.
Note that Concat() is a lazily evaluated linq method. When you actually enumerate it results are produced. It doesn't modify anything, it's more like a description of how to produce a sequence.
So each time through the loop you're assigning a new IEnumerable that describes a concatentaion of an empty list followed by the property that you retrieved with reflection to equipmentResults. Then at the end you return the final one of these concatenations of an empty list and retrieved property.
If you want all of them together, you should concatenate each of them to the result of the previous concatenation, not to an empty list.
i have recently stumbled upon a project(8-puzzle solver using A* alg) in which some codes are weird to me , because i have never seen the likes of it before .
what does this line mean ? what is this ?!
this[StateIndex]
whats this notation ? i cant undersand it at all !
i posted a sample of the class so that you can see it almost all together .
and one more question , is it not wrong to have a class implemented like StateNode? it used only a constructor to initialize its fields , and yet worst, declared them all public ! should he/she not have implemented Propertise for this task?
public enum Direction
{
Up = 1, Down = 2, Left = 3, Right = 4, UpUp = 5, DownDown = 6, LeftLeft = 7, RightRight = 8, Stop = 9
}
class StateNode
{
public int Parent;
public List<int> Childs;
public Direction Move;
public Direction ParentMove;
public byte[,] State;
public byte Depth;
public byte NullRow;
public byte NullCol;
public StateNode()
{ }
public StateNode(int NewParent, Direction NewMove, Direction ParentMove, byte NewDepth, byte NewNullRow, byte NewNullCol)
{
this.Parent = NewParent;
this.State = new byte[5, 5];
this.Move = NewMove;
this.ParentMove = ParentMove;
this.Depth = NewDepth;
this.NullRow = NewNullRow;
this.NullCol = NewNullCol;
this.Childs = new List<int>();
}
}
class StateTree : List<StateNode>
{
public static long MakedNodes;
public static long CheckedNodes;
public static byte MaxDepth;
public List<int> Successor1(int StateIndex)
{
List<int> RetNodes = new List<int>();
StateNode NewState = new StateNode();
//Up
if (this[StateIndex].NullRow + 1 <= 3 && this[StateIndex].ParentMove != Direction.Up)
{
NewState = ChangeItemState(this[StateIndex], StateIndex, Direction.Up, Direction.Down, Convert.ToByte(this[StateIndex].Depth + 1), this[StateIndex].NullRow, this[StateIndex].NullCol, Convert.ToByte(this[StateIndex].NullRow + 1), this[StateIndex].NullCol);
this.Add(NewState);
RetNodes.Add(this.Count - 1);
StateTree.MakedNodes++;
this[StateIndex].Childs.Add(this.Count - 1);
if (NewState.Depth > StateTree.MaxDepth)
StateTree.MaxDepth = NewState.Depth;
}
//Down
//Left
//Right
return RetNodes;
}
}
In your concrete case it's just access to the element, as it used inside the class that is derived from the List<T>
But it can be also indexer which enables index acces to your class object.
For example declare class like this:
public class ListWrapper
{
private List<int> list = ...
public int this[int index]
{
return list[index];
}
}
and after use it like
var lw = new ListWrapper();
//fill it with data
int a = lw[2]; //ACCESS WITH INDEX EVEN IF THE TYPE IS NOT COLLECTION BY ITSELF
this[StateIndex] is using the current class' indexer property. The indexer property is what allows you to access an element in a collection or list object as if it was an array. For instance:
List<string> strings = new List<string>();
strings.Add("Item 1");
strings.Add("Item 2");
strings.Add("Item 3");
string x = strings[0]; // Returns the first item in the list ("Item 1")
When you want to access the indexer property of your own class, however, you have to preface it with the this keyword. You'll notice that in your example, the StateTree class doesn't implement an indexer property, so that may be adding to your confusion. The reason it works is because StateTree inherits from List<StateNode> which does implement an indexer property.
But don't get confused between classes with indexer properties and arrays. Arrays are a completely different thing, though the syntax is similar. An array is a list of objects which can be accessed by an index. An indexer property is an unnamed property of a single object that acts as an array. So for instance, List<string> has an indexer property, so you can access the items it contains using the same syntax as an array index (as shown in the above example). However, you can still make an array of List<string> objects. So for instance:
List<string> strings1 = new List<string>();
strings1.Add("Item 1.1");
strings1.Add("Item 1.2");
List<string> strings2 = new List<string>();
strings2.Add("Item 2.1");
strings2.Add("Item 2.2");
List<string>[] stringsArray = new List<string>[] { strings1, strings2 };
object result;
result = stringsArray[0]; // Returns strings1
result = stringsArray[0][1]; // Returns "Item 1.2"
result = stringsArray[1][0]; // Returns "Item 2.1"
As far as StateNode goes, there's nothing technically wrong with it, and it's not unusual to have a constructor that initializes all the field values, but it's always better to use properties instead of public fields.
its Indexed Properties in C# .net .
you can check Tutorial : http://msdn.microsoft.com/en-us/library/aa288464(v=vs.71).aspx check here
this[StateIndex] is pointing to an element within the class. Because StateTree inherits from a List<T>, you have a collection that's accessible by index (in this case this[N] where N is the element's index.
this[StateIndex] is how you give a class and indexed property e.g
public class IndexedClass
{
private List<String> _content;
public IndexedClass()
{
_content = new List<String>();
}
public Add(String argValue)
{
_content.Add(argValue);
}
public string this[int index]
{
get
{
return _content[index];
}
set
{
_content[Index] = value;
}
}
}
so now you can do
IndexedClass myIndex = new IndexedClass();
myIndex.Add("Fred");
Console.Writeline(myIndex[0]);
myIndex[0] = "Bill";
Console.Writeline(myIndex[0]);
As for statenode if it's local to the class (a helper) then you could argue it as okay, I don't like it though, another ten minutes work it could be done properly. If it's public in the assembly, then it's not accpetable in my opinion. But that is an opinion.
I'm trying to find a struct I created earlier that has a specific value. Once I found it, I want to set variables on that struct. I don't know how to do this. Is there a better way of doing this? Maybe classes? Or should structs work?
For example, my struct:
public struct MyTest
{
public string device;
public string status;
public string revision;
public string number;
public string ledmo;
}
My Test Code:
MyTest thisTest=new MyTest();
thisTest.device=blah;
thisTest.number=blah2;
MyTest thisTest2=new MyTest();
thisTest2.device=blah5;
thisTest2.number=blah6;
//Another Part in my code.
//Need to find the MyTest Structure that 'device' variable = the string 'blah'
var Foundit=MyTest.find(device==blah);
Foundit.revision=blah9999;
I'd use a class, because Mutable structs are evil
Basically, because every struct is copied, even if you do find the right struct, you'll only ever change one copy. Lets say MyTest.find finds thisTest2 what happens is this
var Foundit = MyTest.Find(device==blah);
// The line above has made a copy of thisTest2, that copy is in FoundIt
Foundit.revision = "blah9999";
// You've changed revision in the copy of thisTest2,
// therefore the contents of thisTest2 remain unchanged
To do this with a class you'll need to keep every instance of the class you create in a list or other data structure, so you know you can look it up.
If you do this you also need to tell the list when you're finished with each object, otherwise they'll hang around forever and never get garbage collected.
Before I go any further, are you sure this is the best way to solve this problem?
Anyway, say your class is MyData, you can put a static factory method on this called Create, which will put each new MyData object into a list.
public class MyData
{
private static List<MyData> allMyDatas = new List<MyData>();
public static IEnumerable<MyData> AllInstances
{
get {return allMyDatas;}
}
public string Device {get; set;}
public string Status {get; set;}
public string Revision {get; set;}
public string Number {get; set;}
public string Ledmo {get; set;}
private MyData() // Private ctor ensures only a member
{ // function can create a new MyData
}
public static MyData Create()
{
var newData = new MyData();
allMyDatas.Add(newData);
return newData;
}
public static void Delete(MyData itemToRemove)
{
allMyDatas.Remove(itemToRemove);
}
}
Everywhere you use a MyData you'll need to Delete it when you're finished with it.
Your code becomes
var thisTest = MyData.Create();
thisTest.Device = "blah";
thisTest.Number = "blah2";
var thisTest2 = MyData.Create();
thisTest2.Device = "blah5";
thisTest2.Number = "blah6";
//Another Part in my code.
//Need to find the MyData Structure that 'device' variable = the string 'blah'
var Foundit = MyData.AllInstances.FirstOrDefault(md => md.Device == "blah");
if(Foundit != null)
Foundit.Revision = "blah9999";
Changing FoundIt now also changes thisTest
P.S.: It's important that nothing outside MyData can new an instance of MyData. If it could, then there would be an instance of MyData that you couldn't find in AllInstances. Declaring the constructor private means a compiler error will be generated if code outside MyData tries something like var someData = new MyData
To be able to find instances of an object created earlier, these instances need to be saved somewhere.
One solution would be to put them into a list and later search that list:
var list = new List<MyTest>();
MyTest thisTest=new MyTest();
thisTest.device=blah;
thisTest.number=blah2;
list.Add(thisTest);
MyTest thisTest2=new MyTest();
thisTest2.device=blah5;
thisTest2.number=blah6;
list.Add(thisTest2);
Now you can search using LINQ:
var foundItems = list.Where(x => x.device == "blah");
foreach(var foundItem in foundItems)
{
foundItem.revision = "blah9999";
}
Please note:
This only works when you use classes instead of structs as Binary Worrier points out in his comment.
In this case a class would work better because of the dynamic string size and the fact that there are so many strings.
With your test code, you should be storing a List<MyTest> somewhere in that class and adding thisTest and thisTest2 to the list. You can later retrieve specific values (or all the values of a certain device) with the FindAll or similar methods.
List<MyTest> list = new List<MyTest>();
//add MyTests here...
var foundIt = list.FindAll(x => x.device == "blah");
You can use lists and Linq for that.
var test = new List<MyTest>();
//Add some items
var foundIt = test.SingleOrDefault(test => test.device == "abc");//Maximum one
if(foundIt != null)//Use a class for MyTest.
foundIt.device = "123"
In C#, is there an inline shortcut to instantiate a List<T> with only one item.
I'm currently doing:
new List<string>( new string[] { "title" } ))
Having this code everywhere reduces readability. I've thought of using a utility method like this:
public static List<T> SingleItemList<T>( T value )
{
return (new List<T>( new T[] { value } ));
}
So I could do:
SingleItemList("title");
Is there a shorter / cleaner way?
Thanks.
Simply use this:
List<string> list = new List<string>() { "single value" };
You can even omit the () braces:
List<string> list = new List<string> { "single value" };
Update: of course this also works for more than one entry:
List<string> list = new List<string> { "value1", "value2", ... };
var list = new List<string>(1) { "hello" };
Very similar to what others have posted, except that it makes sure to only allocate space for the single item initially.
Of course, if you know you'll be adding a bunch of stuff later it may not be a good idea, but still worth mentioning once.
Michael's idea of using extension methods leads to something even simpler:
public static List<T> InList<T>(this T item)
{
return new List<T> { item };
}
So you could do this:
List<string> foo = "Hello".InList();
I'm not sure whether I like it or not, mind you...
A different answer to my earlier one, based on exposure to the Google Java Collections:
public static class Lists
{
public static List<T> Of<T>(T item)
{
return new List<T> { item };
}
}
Then:
List<string> x = Lists.Of("Hello");
I advise checking out the GJC - it's got lots of interesting stuff in. (Personally I'd ignore the "alpha" tag - it's only the open source version which is "alpha" and it's based on a very stable and heavily used internal API.)
new[] { "item" }.ToList();
It's shorter than
new List<string> { "item" };
and you don't have to specify the type.
Use an extension method with method chaining.
public static List<T> WithItems(this List<T> list, params T[] items)
{
list.AddRange(items);
return list;
}
This would let you do this:
List<string> strings = new List<string>().WithItems("Yes");
or
List<string> strings = new List<string>().WithItems("Yes", "No", "Maybe So");
Update
You can now use list initializers:
var strings = new List<string> { "This", "That", "The Other" };
See http://msdn.microsoft.com/en-us/library/bb384062(v=vs.90).aspx
Yet another way, found on "C#/.Net Little wonders" (unfortunately, the site doesn't exist anymore):
Enumerable.Repeat("value",1).ToList()
For a single item enumerable in java it would be Collections.singleton("string");
In c# this is going to be more efficient than a new List:
public class SingleEnumerator<T> : IEnumerable<T>
{
private readonly T m_Value;
public SingleEnumerator(T value)
{
m_Value = value;
}
public IEnumerator<T> GetEnumerator()
{
yield return m_Value;
}
IEnumerator IEnumerable.GetEnumerator()
{
yield return m_Value;
}
}
but is there a simpler way using the framework?
I've got this little function:
public static class CoreUtil
{
public static IEnumerable<T> ToEnumerable<T>(params T[] items)
{
return items;
}
}
Since it doesn't prescribe a concrete return type this is so generic that I use it all over the place. Your code would look like
CoreUtil.ToEnumerable("title").ToList();
But of course it also allows
CoreUtil.ToEnumerable("title1", "title2", "title3").ToArray();
I often use it in when I have to append/prepend one item to the output of a LINQ statement. For instance to add a blank item to a selection list:
CoreUtil.ToEnumerable("").Concat(context.TrialTypes.Select(t => t.Name))
Saves a few ToList() and Add statements.
(Late answer, but I stumbled upon this oldie and thought this could be helpful)
Try var
var s = new List<string> { "a", "bk", "ca", "d" };
You can also do
new List<string>() { "string here" };
I would just do
var list = new List<string> { "hello" };
Inspired by the other answers (and so I can pick it up whenever I need it!), but with naming/style aligned with F# (which has a standard singleton function per data structure*):
namespace System.Collections.Generic
{
public static class List
{
public static List<T> Singleton<T>(T value) => new List<T>(1) { value };
}
}
* except for ResizeArray itself of course, hence this question :)
In practice I actually name it Create to align with other helpers I define such as Tuple.Create, Lazy.Create[2], LazyTask.Create etc:
namespace System.Collections.Generic
{
public static class List
{
public static List<T> Create<T>(T value) => new List<T>(1) { value };
}
}
[2]
namespace System
{
public static class Lazy
{
public static Lazy<T> Create<T>(Func<T> factory) => new Lazy<T>(factory);
}
}
The declarations make it so easy now to do in C# 10.0 that I don't think theres a need for any helper. Just add the new(){} around any value you want to cast to a list.
List<string> values = new() { "single value" };
If someone landed on this page and trying to add object instead of string, then this worked for me.
new List<myObj> { new myObj{propertName=propstryValue }
, new myObj{propertName=propstryValue }, new myObj{propertName=propstryValue }
};
You need to create an inheritor from the List<> class
public class SingletonList<T> : List<T>
{
public SingletonList(T element) : base(1)
{
this.Add(element);
}
}
and you can use it instead of the base List<> class
var singletonList = new SingletonList<string>("Hello World!");