monoDevelop ubuntu c# Class List has not the elementAt method - c#

I'm trying to run c# on Ubuntu. So, I downloaded the monoDevelop from the Software Center which version is 3.0.4.3.
I think the problem is about the c# class library version, but i don't know where to see it or to apply a more recent one so that I could use the elementAt method in the List Class.
Thanks

On the documentation there is an indexer that you can use instead: http://docs.go-mono.com/?link=P%3aSystem.Collections.Generic.List%3cT%3e.Item
EDIT
You do use an indexer just like you would do for retrieving/setting an array element :
var list = new List<string>();
list.Add("hello !");
var s = list[0];

Related

Can you make a class enumerable via extension methods? In particular, System.Range

I'm using the latest C# 8 right now, I was toying around with the new System.Range, and wanted to see if something like
foreach (int i in 5..8)
{
}
was possible, but at the time of writing this (using the absolute cutting edge preview) is giving me an error.
I then wondered if I could make it enumerable by doing something like the following in a static class, since maybe the foreach loop doesn't actually care and just wants the existence of some method to be available, so I tried:
public static IEnumerator GetEnumerator(this Range range)
{
// ...
}
however the compiler was not happy with this.
Is this possible? Or am I just implementing enumerable wrong? The error message in the IDE was telling me that GetEnumerator() needs to be available for foreach to run, however since I don't have access to the class and can't simply do : IEnumerable<int> and then generate the methods from it and do what is needed, I don't know if this means I'm stuck or whether I'm coding this incorrectly.
My error:
foreach (int i in 1..5)
{
Console.WriteLine(i);
}
[CS1579] foreach statement cannot operate on variables of type 'Range' because 'Range' does not contain a public instance definition for 'GetEnumerator'
and
$ dotnet --version
3.0.100-preview8-013656
with a project targeting netcoreapp3.0 and the C# language level is preview
No, the foreach loop doesn't work with extension methods, unlike (say) await. It is pattern-based in that it doesn't require implementing IEnumerable<T> or IEnumerable - if you have an appropriate GetEnumerator() instance method returning an appropriate type (with MoveNext() and Current members), that's fine. But the compiler doesn't look for a GetEnumerator() extension method like you've got. It has been proposed, but I don't know of any plan to do this, and I'd be very surprised if it were in C# 8 (given the list of features).
You'd need to write an extension method like this:
public static IEnumerable<int> AsEnumerable(this Range range)
{
...
}
and then you could use
foreach (int x in (1..5).AsEnumerable())
... but you'd still need to work out what to do if either index is "from the end" instead of "from the start", and I'm not sure it's terribly useful to have that as an execution-time-only check, really.
Basically, ranges are designed mostly for slicing within another context rather than being standalone.

Convert Object to an array of Ushort in c#

I'm fairly new to C# but i'm looking to convert an object to an array of unsigned shorts. The original data is an array of WORD's (numerical value WORD) passed as an object. I've attempted the following but keep getting an error.
object temp = Agent.Port("PumpPressure1_01").Value;
ushort[] PP1_01 = ((IEnumerable)temp).Cast<object>()
.Select(x => x == null ? x.ToUshort())
.ToArray();
When I run this I get the following error:
'System.Collections.Generic.IEnumerable<T>' requires '1' type arguments.
The namespaces I used when I get the above error are:
using System.Linq;
using System.Text; // Don't think this is required but added it in case
If I add the following namespaces:
using System.Collections;
using System.Collections.Generic;
I get the following error.
'System.Linq.ParalleIEnumerable.Select<TTSource,TResult>()' is not supported by the language
I'm sure this is an obvious issue but I've been hunting the net for a while and can't find a solution. My best guess is that the Select function isn't correct as this was originally designed to convert an object to an array of strings.
Any help would be great.
Thanks
IEnumerable is a generic interface, so you have to declare the datatype you are using...
To be honest though, I would want to check what that call to
object temp = Agent.Port("PumpPressure1_01").Value;
is actually returning - by inspecting it in the debugger... If it is simply returning a reference to an array of a numeric type, you should be able to simply cast it. What you are doing though is trying to cast each individual item within the array - I suspect that's not what you should be doing - which would be casting the array itself.
Can you give us any API documentation for the Port method on the Agent object so I can see what it is meant to return? Can you try the inspection and see what that gives you?
Why you casting to IEnumerable and then casting it back to object if your temp variable is already of type object?
Also IEnumerable<T> is a generic interface and must specify exact type (as exception also says to you). If you have an array of integers and you want to work with them it should be IEnumerable<int>
Thanks for all the help and feedback.
Unfortunately I was't paying enough attention to the warnings that was posted which seems to be causing the issue.
Warning: Reference to type 'System.Func '2' claims it is defined in 'c:\Windows\Microsoft.NET\Framework64\v2.0.50727mscorlib.dll'. but it could not be found
It seems that there is some issue with the .NET reference. I have another VM which I tested the following solution on and it seemed to work without issue. Looks like I'll have to reinstall the software package to get it to work on the VM i want to use.
The software package I'm using is a custom package that uses C# to build solutions with prebuilt classes made to look like plug and play blocks. You can connect the blocks together drawings lines from one input/output of a block to another. You can then build C# code inside the blocks. Basically c# for dummy's like me..
Example of the blocks:
As for the code, I did have to make some changes as follows but now works a treat. Agent.Port("PumpPressure1_01").Value.RawValue is used to reference the particular ports on the block.
object temp = (object)Agent.Port("PumpPressure1_01").Value.RawValue;
UInt16[] PP1_01 = ((System.Collections.IEnumerable)temp).Cast<object>()
.Select(x => Convert.ToUInt16(x))
.ToArray();
foreach(UInt16 x in PP1_01)
{
Agent.LogDebug("values: " + x.ToString());
}
Again, thanks for all the help. Just need to resolve the issue with the library reference now.

Create ArrayList in one step

I'm desperately trying to create an ArrayList out of objects of an enumeration in one step in C# with Visual Studio 2012.
It should look like something of the following:
new ArrayList( {class1.enum.sample1, class1.enum.sample2, class1.enum.sample3} );
When I'm writing it in two lines, it works:
class1.enum[] array = {class1.enum.sample1, class1.enum.sample2, class1.enum.sample3};
ArrayList test = new ArrayList(ha);
But I need to write it in one line. Could you help me, please?
You need another collection like an array to be able to use the collection initializer:
var al = new ArrayList { new[] { class1.enum.sample1, class1.enum.sample2, class1.enum.sample3 } };
But there is no reason to use the old ArrayList anymore. In this case you could use a List<class1.enum> (apart from the fact that enum is a keyword).
You do not need parenthesis () for array list initializer. You can initialize in a single line as under.
ArrayList test = new ArrayList{class1.enum.sample1, class1.enum.sample2, class1.enum.sample3}
Array list should be replace with generic list unless you have solid reason to use Arraylist. You can find more about using generic list in Benefits of Generics on MSDN

Is there .net magic to get parameter values by name in console application?

I've been developing .net console applications using C# and have always just dictated what order parameters must be inserted in so that args[0] is always start date and args[1] is always end date, for example.
however I would like to move over to using named parameters so that any combination of parameters can be sent in any order, such as the typical "-sd" would prefix a start date.
I know I could parse through the args[] looking for "-" and then read the name and look the next position for the accompanying value, but before doing that wanted to see if there was any kind of baked in handling for this rather standard practice.
is there something like this out there already that could do as such:
DateTime startDate = (DateTime)((ConsoleParameters)args[])["sd"]
I'm using C# and .Net 4
There is nothing built into the core framework.
A lot of people think NDesk.Options is useful for this sort of thing. Check out this example (taken directly from the provided link):
string data = null;
bool help = false;
int verbose = 0;
var p = new OptionSet () {
{ "file=", v => data = v },
{ "v|verbose", v => { ++verbose } },
{ "h|?|help", v => help = v != null },
};
List<string> extra = p.Parse (args);
Yes, the "magic" is that this is a common problem and it has been adequately solved. So I recommend using an already written library to handle parsing command line arguments.
CommandLineParser has been great for me. It is reasonably documented and flexible enough for every type of command line argument I've wanted to handle. Plus, it assists with usage documentation.
I will say that I'm not the biggest fan of making a specific class that has to be adorned with attributes to use this library, but it's a minor point considering that it solves my problem. And in reality forcing that attributed class pushes me to keep that class separate from where my app actually retrieves it's settings from and that always seems to be a better design.
You can use NDesk.Options.
There is no such a thing as named parameters. "-sd" is just a choice for a specific application. It can be "/sd" as well. Or "sd=". Or whatever you want.
Since there are no named parameters, there is nothing inside .NET Framework which let you use the "-sd" syntax.
But you can quite easily build your own method to get a set of "named parameters" for your app.
Edit: or, even better, you can use an existing library, like suggested in other answers.
Edit: reading the answer by #Sander Rijken, I see that I was wrong: there were still an implementation of "-sd" syntax in .NET 4.0 before the release. But since it was dropped before the final release, the only ways are still to create your own method or to use an existing library.

How to convert ArrayList to an array of structure?

Here I have:
Public Structure MyStruct
Public Name as String
Public Content as String
End Structure
Dim oStruct as MyStruct = New MyStruct()
oStruct.Name = ...
oStruct.Content = ...
Dim alList as ArrayList = new ArrayList()
alList.Add(oStruct)
I'd like to convert the ArrayList to a static strongly-typed Array of type MyStruct. How can I do that? I had no luck with ToArray.
I am using .NET Framework 2.0.
You have to cast the result of ToArray
MyStruct[] structs = (MyStruct[]) alList.ToArray(typeof(MyStruct));
I assume that since you are using ArrayList, you are using 1.1?
In which case, I suspect the following would work:
ArrayList list = new ArrayList();
MyStruct[] array = new MyStruct[list.Count];
list.CopyTo(array);
(edit - Bill's ToArray usage is more convenient - I didn't know about that one, but then, I very rarely [if ever] use ArrayList)
However, if MyStruct really is a struct, then I cannot say strongly enough that mutable structs are a bad idea - i.e. where you can set .Name and .Content after creation. Structs should almost always be immutable. In reality, your MyStruct looks like it should be a class. Also - I'm not "up" on VB, but are they public fields? Again - not recommended - properties would be preferable. I don't know about VB, but C# 3.0 has some very terse syntax for this:
public class SomeType
{
public string Name {get;set;}
public string Content {get;set;}
}
If you are using 2.0 or above, consider List<T> instead of ArrayList.
ToArray is the right way to go. In C# it would be:
MyStruct[] array = (MyStruct[]) alList.ToArray(typeof(MyStruct));
Are you stuck using 1.1, btw? If you're using 2.0, can you shift to List<T> instead?
This worked for me
Dim array As MyStruct() = alList.ToArray(GetType(MyStruct))
If you are running Visual Studio 2008 you can use a List object.
Dim alList As New List(Of MyStruct)
alList.Add(oStruct)
In case you're using 2.0 or later, you might want to define your arraylist like this:
Dim alList as New List(Of MyStruct)()
alList.Add(oStruct)
This will give you the same semantics as an array (lookup by index, strong typing, IEnumerable support, etc).
There are only two reasons in .Net 2.0 and later to use an array instead of a generic list:
You know with absolute certainty the number of items you have, and know that the count won't change. This is surprisingly rare.
You need to call a function that requires an array. There are still a fair number of these lurking in the BCL, but your own code should be asking for IEnumerable<T>, IList<T>, or ICollection<T>, and only rarely an array.
Finally, this is kind of nit-picky, but there are two stylistic points I want to address in the code you posted. First, note the abbreviated syntax I used to create the New List<MyStruct>. There's no = symbol and you don't have to key in the type name twice. That was support back in 1.1 as well, so there's no excuse there. Secondly, the style guidelines for .Net published by Microsoft on MSDN (see the general naming conventions section) specifically recommend against hungarian warts like 'o' or 'a'. It was nice for VB6/VBScript, which were loosely typed, but .Net is strongly typed, making the warts, well, wart-ugly.

Categories