|
ooh i see,
how do i add this to the string class? and isn't string[] not a class in the first place?
Thanks,
Marios
|
|
|
|
|
Well it derives from System.Array doesn't it?
By the way, I implement that method as:
public static string[]
Concat
(
string[] first
,
string[] second
)
{
string[] result = null ;
if ( ( first != null ) && ( second != null ) &&
( first.Rank == 1 ) && ( second.Rank == 1 ) )
{
result = new string [ first.Length + second.Length ] ;
first.CopyTo ( result , 0 ) ;
second.CopyTo ( result , first.Length ) ;
}
else
{
throw new System.Exception ( "Can only concatenate one-dimensional arrays" ) ;
}
return ( result ) ;
}
|
|
|
|
|
AFAIK you can't do what you want, since Array class isn't yours and probably sealed.
If you insist on using the + operator I am afraid the only thing you can do is come up
with an entirely new class (myStringCollection) and implement all the properties, methods
and operators you need. Such class obviously could contain an array, an ArrayList or a
List<string> to hold the actual data.
If the + operator is not mandatory, have a look at the StringCollection class, it knows
how to accept and add string arrays.
Luc Pattyn [Forum Guidelines] [My Articles]
this months tips:
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use PRE tags to preserve formatting when showing multi-line code snippets
|
|
|
|
|
No one mentioned Extension Methods, mightn't they help here?
|
|
|
|
|
PIEBALDconsult wrote: No one mentioned Extension Methods, mightn't they help here?
I haven't studied the subject and am not planning to any time soon. There still is much
to digest in 2.0
Do you expect them to be available on a sealed class (I'm still assuming Array is sealed).
Luc Pattyn [Forum Guidelines] [My Articles]
this months tips:
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use PRE tags to preserve formatting when showing multi-line code snippets
|
|
|
|
|
Luc Pattyn wrote: on a sealed class
That seems to be the point of them; they behave as if they are part of the class even though they aren't.
I don't expect to use them either, but this may be a case where they are useful. The problem being that the arrays have to be compatible.
|
|
|
|
|
OK, I did read this blog page[^] and do like the idea a little.
I have some use for it, for one I did create my own LP_StringList (back in 1.0 times) which
solved the casting problem and added some methods I deemed useful. I even have an
LP_StringArray with a Concat, not as nicely implemented as yours though.
Luc Pattyn [Forum Guidelines] [My Articles]
this months tips:
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use PRE tags to preserve formatting when showing multi-line code snippets
|
|
|
|
|
Luc Pattyn wrote: not as nicely implemented as yours though.
What? That old thing?
|
|
|
|
|
Hi PIEBALD,
I wrote mine in the early days of .NET when I was not yet aware of the Array.CopyTo method;
after todays rework it deals with null arguments, like so:
public static string[] Concat(string[] sa1, string[] sa2) {
int len1=0;
if (sa1!=null) len1=sa1.Length;
int len2=0;
if (sa2!=null) len2=sa2.Length;
string[] sb=new string[len1+len2];
if(sa1!=null) sa1.CopyTo(sb, 0);
if(sa2!=null) sa2.CopyTo(sb, len1);
return sb;
}
so I got rid of the for loops...
Luc Pattyn [Forum Guidelines] [My Articles]
this months tips:
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use PRE tags to preserve formatting when showing multi-line code snippets
|
|
|
|
|
When I don't want to throw on a null argument I try to find a reasonable default (and avoid checkin' it twice).
public static string[] Concat(string[] sa1, string[] sa2)
{
if ( sa1 == null ) sa1 = new string [ 0 ] ;
if ( sa2 == null ) sa2 = new string [ 0 ] ;
string[] sb = new string [ sa1.Length + sa2.Length ] ;
sa1.CopyTo ( sb , 0 ) ;
sa2.CopyTo ( sb , sa1.Length ) ;
return sb ;
}
|
|
|
|
|
No way, I am not going to create two objects that I don't need at all.
At the cost of two null tests, I'll avoid these dummy arrays and their futile Length
and CopyTo operations.
I would consider your cleaner approach on a bigger job, but in a simple leaf method
I go for minimal cycles. And if I were to need an empty array like that, I would invest
in a single static one and use it over and over.
BTW: why isn't there a ??= operator allowing sa1 ??= new string[0]; ??
Luc Pattyn [Forum Guidelines] [My Articles]
this months tips:
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use PRE tags to preserve formatting when showing multi-line code snippets
|
|
|
|
|
Yeah, that may not be a good usage for that technique, mine of course throws an exception on null, though I may change that to yours if I ever need to allow nulls.
I suppose a static empty array might be better than what I wrote.
|
|
|
|
|
Extension methods may also allow the addition of HighestSetBit to ulong , etc.
Now I'm getting excited about them!
|
|
|
|
|
You are absolutely right, and since I have dozens of those nasty little bit manipulation
things, that will speed up my interest in 3.0
Luc Pattyn [Forum Guidelines] [My Articles]
this months tips:
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use PRE tags to preserve formatting when showing multi-line code snippets
|
|
|
|
|
public frmEditor(string[] ProfileToUse)
{
ProfilesTypes = ProfileToUse;
dbProfiles.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source = G:\\CSharp\\Project.mdb;Jet OLEDB:Database Password=password1";
InitializeComponent();
}
string ProfileTypesInUse = "";
bool isUpdate = false;
private void frmEditor_Load(object sender, EventArgs e)
{
if (ProfilesTypes[0] == "ProfileID")
{
try
{
isUpdate = true;
OleDbCommand cmdGetProfileFields = new OleDbCommand("select type_id from proProfiles where profile_id= " + ProfilesTypes[1], dbProfiles);
if (dbProfiles.State == ConnectionState.Closed)
dbProfiles.Open();
string[] sep = new string[1];
sep[0] = ",";
string[] ptu = cmdGetProfileFields.ExecuteScalar().ToString().Split(sep, StringSplitOptions.RemoveEmptyEntries); //I keep getting an error "Object reference not set to an instance of an object.
for (int i = 0; i < ptu.Length; i++)
Can someone please help me with this problem??
|
|
|
|
|
Are you using Visual Studio? ...Have you tried using the debugger? ...put a breakpoint on that line and when you hit F5, it should stop execution on that line....put "cmdGetProfileFields" and "sep" into your watch window and see what is returned to you....if either of those show the value of "object reference not set to an instance of an object", then you've pinpointed the cause of your exception
"I need build Skynet. Plz send code"
|
|
|
|
|
It gives me ptu value null and sep value is {Dimensions:[1]} in the Watch Window. What should I do now? I need {Dimensions:[2]} for ptu
|
|
|
|
|
T4AMD wrote: string[] ptu = cmdGetProfileFields.ExecuteScalar().ToString().Split(sep, StringSplitOptions.RemoveEmptyEntries);
seems like ExecuteScalar returns null.
if you want to be sure about this, split the line in two:
object obj=cmdGetProfileFields.ExecuteScalar();
string[] ptu = obj.ToString().Split(sep, StringSplitOptions.RemoveEmptyEntries);
and either add a null test, or use the debugger again.
If it is null, I can not tell you why...
Luc Pattyn [Forum Guidelines] [My Articles]
this months tips:
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use PRE tags to preserve formatting when showing multi-line code snippets
|
|
|
|
|
I keep getting the same error when i tried your code Luc, and I think that ExecuteScalar is returning a null value
|
|
|
|
|
I use the code below to remove commants from xml strings.
The C# guru wrote me: that this code is wrong
since while iterating a collection it is not allowed to remove its element.
He wrote this is .NET bug: this code sholud throw exception.
Please confirm, is this .NET bug ?
How to remove comments from xml string (fix this code)?
using System;<br />
using System.Windows.Forms;<br />
using System.Xml;<br />
<br />
public class Test<br />
{<br />
[STAThread]<br />
static void Main()<br />
{<br />
XmlDocument xDoc = new XmlDocument();<br />
xDoc.PreserveWhitespace = false;<br />
xDoc.LoadXml(xml);<br />
XmlNodeList list = xDoc.SelectNodes("//comment()");<br />
foreach (XmlNode node in list)<br />
{<br />
node.ParentNode.RemoveChild(node);<br />
}<br />
}<br />
<br />
const string xml = @"<?xml version=""1.0""><br />
<Report><!-- --></Report><br />
";<br />
<br />
}<br />
Andrus
|
|
|
|
|
No, it's not a bug. He's saying it should be, but that would involve changes to the compiler to add mind reading capability.
Enumerating a collection is valid only so long as the collection remains unchanged. Adding and removing items changes the collection. If either of these operations happen, the Enumerator is automatically invalid because the bounds of the enumeration are no longer known and it's also unknown if the current item even exists anymore. When this happens, the Enumerator is no longer is a known state and cannot be recovered. It's behavior is undefined.
Enumerators do do not exclusive access to the collection, so enumerating one is inherently not a thread-safe operation. The collection CAN be modified from outside the enumeration. If this happens, the enumerator is, again, invalid.
If you're going to modify a collection, you cannot use foreach . You must use a normal for statement with an index into the array of items.
|
|
|
|
|
I did'nt understand your reply. You wrote that this code modifies same collection inside foreach loop which is not allowed.
.NET does not throw exception for this code.
So it is .NET bug, isn't it ?
Chris Shepherd explains:
A cloned IEnumerable instance is *not* the same IEnumerable, by nature. It may have references to the same data, but it
does not necessarily contain the same list of references. If you remove
items from the newly cloned instance, it won't affect its progenitor,
and vice versa. Kind of the point of clone, really.
This code is functionally working with two different IEnumerable objects. Below is an example of effectively what
original code is doing -- removing a subset of items in one list from
another list.
class General<br />
{<br />
class ClassA<br />
{<br />
public string name;<br />
<br />
public ClassA(string nm) { this.name = nm; }<br />
}<br />
<br />
static void Main(string[] args)<br />
{<br />
List<ClassA> listOne = new List<ClassA>();<br />
List<ClassA> listTwo = new List<ClassA>();<br />
<br />
ClassA a = new ClassA("A");<br />
ClassA b = new ClassA("B");<br />
ClassA c = new ClassA("C");<br />
ClassA d = new ClassA("D");<br />
ClassA e = new ClassA("E");<br />
<br />
listOne.AddRange(new ClassA[] { a, b, c, d, e });<br />
listTwo.AddRange(new ClassA[] { a, c, d });<br />
<br />
string msg = "Start Length of listOne: " +<br />
listOne.Count.ToString() +<br />
"\nStart Length of listTwo: " +<br />
listTwo.Count.ToString() +<br />
"\nWhat is removed:\n";<br />
foreach (ClassA z in listTwo)<br />
{<br />
msg += z.name + "\t";<br />
listOne.Remove(z);<br />
}<br />
<br />
Console.WriteLine(msg + "\nLength of listOne: " +<br />
listOne.Count.ToString() +<br />
"\nLength of listTwo: " +<br />
listTwo.Count.ToString());<br />
}<br />
}<br />
Andrus
|
|
|
|
|
AndrusM wrote: You wrote that this code modifies same collection inside foreach loop which is not allowed.
.NET does not throw exception for this code.
So it is .NET bug, isn't it ?
No, it's not a compile time error. There is no way for the compiler to know that the method called "Remove" removes items from the collection. You could call the very same method "Jaxtapose". The name of the method doesn't tell the compiler anything other than "this is a name". The compiler cannot tell what the code inside the method does.
It WILL throw a run-time exception though.
|
|
|
|
|
No, it will *not* cause run time exception in .NET 2 and 3.5.
It removes all comment from XML.
So my question was: Is this .NET but that this code does not cause run-time exception ?
Andrus
|
|
|
|
|
I wasn't talking about your code. I was talking about what the other person said about what should be a "bug". There are a few exceptions to the rule. It would appear that you have found one of them.
|
|
|
|