Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
boo_radley
Dec 30, 2005

Politeness costs nothing
In a c# program, I have some code wrapped in a pre-processor directive:

code:
#if DEBUG
...
#endif
whenever I start an #if block, VS ignores my tab level and puts the #if at column 0. I hate this, and would like to keep these blocks in line with the rest of my code. I looked under Tools | Options | Text Editor | C# | Formatting | Indentation, but I don't see an option that describes what I want. Any ideas?

Adbot
ADBOT LOVES YOU

csammis
Aug 26, 2003

Mental Institution
I don't think it can be done in Visual Studio, but really, why would you want preprocessor commands indented in line with "real" code anyway? #if / #endif blocks are supposed to be extremely visible, that's why the non-compiled code is grayed out.

uXs
May 3, 2005

Mark it zero!

notflipmo posted:

C# + .NET 3.5

Learn me some XML please :(

config.xml:
code:
<config>
	<limit>13312</limit>
	<interval>20</interval>
	<process>utorrent.exe</process>
	<process>dc++.exe</process>
</config>
Basically I would like to write readConfiguration(), which reads the file config.xml
and saves the limit and interval values to ints, and the process values to any suitable storeage class, most likely a string array since I don't expect more than a few process entries.

I figured it would be fun to use an XML configuration file in this project just to have used .NETs mechanisms for XML. But amongst XmlDocuments, XmlReaders, XmlElements, XmlNodes, my brain seems to have melted and I can't seem to grasp it.
I now feel exceedingly dense, after googling all day long and understanding very little :saddowns:

code:
        private void readConfiguration()
        {
            XmlDocument xd = new XmlDocument();
            xd.Load("config.xml");


        }

Beyond this, I haven't been able to make any sense of it all...

Two other options to work with XML if you're not hell-bent on doing it really manually:

* XmlSerializer. Very easy to do. You just put some attributes on a class, give the command to deserialize, and the file gets read and put into an object where you can do whatever.

* Linq to XML. Never used it, but it should work.

ray2k
Feb 7, 2004

Puppet scum beware!

notflipmo posted:

Learn me some XML please :(
:words:

uXs posted:

XmlSerializer. Very easy to do. You just put some attributes on a class, give the command to deserialize, and the file gets read and put into an object where you can do whatever.

Because I'm such a fan of Xml serialization in .Net, I'll touch on what uXs mentioned regarding the XmlSerializer. Basically you'd have a class model with properties decorated to indicate how they go to and from an Xml document. All of the basic value types (strings, ints, etc) are serializable, anything like a class or collection needs a bit more decoration but it's not difficult really. You have to have the default constructor available, along with gets/sets for each serializable property, and for collections as far as I know they have to be in a sub-element. So
code:
<process>utorrent.exe</process>
<process>dc++.exe</process>
Would likely have to be
code:
<processes>
     <process>utorrent.exe</process>
     <process>dc++.exe</process>
</processes>
To get full serialization support. Your serializable class might look like

code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

namespace Butt
{
    [XmlRoot("config")]
    public class Config
    {
        public Config()
        {
        }

        private int _limit = 0;
        private int _interval = 0;
        private List<string> _processes = new List<string>();

        [XmlElement("limit")]
        public int Limit 
        {
            get { return _limit; }
            set { _limit = value; }
        }

        [XmlElement("interval")]
        public int Interval 
        {
            get { return _interval; }
            set { _interval = value; }
        }        
        
        [XmlArrayItem("process")]
        [XmlArray(ElementName="processes")]
        public List<string> Processes 
        {
            get { return _processes; }
            set { _processes = value; }
        }
    }
}
Having said all that, getting to and from xml and the object instances is making a couple calls to XmlSerializer.Deserialize/Serialize and writing/reading from a Stream of your creation.

gibbed
Apr 10, 2006

ray2k posted:

Having said all that, getting to and from xml and the object instances is making a couple calls to XmlSerializer.Deserialize/Serialize and writing/reading from a Stream of your creation.
Well, it looks like I'm rewriting all of my XML loading code now :aaa:.

notflipmo
Feb 29, 2008
'

ray2k posted:

Because I'm a golden god...
While csammis solution got this little project past that particular hump, your post is an absolute godsend for the larger project that's coming up. Thank you very much. :dance:

biznatchio
Mar 31, 2001


Buglord

ray2k posted:

and for collections as far as I know they have to be in a sub-element. So
code:
<process>utorrent.exe</process>
<process>dc++.exe</process>
Would likely have to be
code:
<processes>
     <process>utorrent.exe</process>
     <process>dc++.exe</process>
</processes>
To get full serialization support.

Not true at all. You can have identical tags within a parent tag contribute to a collection property on the parent tag's corresponding class by decorating the collection property with one or more [XmlElement] attributes, and no [XmlArray] or [XmlArrayItem] attributes.

In other words, replace your Processes property definition from your example with this instead:

code:
        [XmlElement("process"), typeof(string)]
        public List<string> Processes 
        {
            get { return _processes; }
        }
to get a serialization schema that corresponds to your first XML example.

(Also note that for collections in an XML serializable class, you don't need to expose a public setter -- in fact it's bad form to. Initialize the collection field to an empty collection in your constructor, and the deserialization process will automatically add to the collection as expected, by calling Add() on the value returned by the getter.)

biznatchio fucked around with this message at 04:01 on Mar 25, 2008

ray2k
Feb 7, 2004

Puppet scum beware!

biznatchio posted:

:words:

I had a feeling that there was a way to get repeated elements into a collection without nesting into a sub-element (hence the 'as far as I know'), but thanks for showing how, regardless. And the setter on the collection thing is just a force of habit. Good catch, though.

Norton Ghostride
Apr 30, 2006

by Y Kant Ozma Post
Is there any way to get a vertical scrollbar to always show up on a SplitPanel control, whether or not the scrollbar is necessary?

Or any control, for that matter?

notflipmo
Feb 29, 2008
'

biznatchio posted:

In other words, replace your Processes property definition from your example with this instead:

code:
        [XmlElement("process"), typeof(string)]
        public List<string> Processes 
        {
            get { return _processes; }
        }

Am I entirely mistaken if I assume the above contains a typing error and should be like so:
code:
        [XmlElement("process", typeof(string))]
        public List<string> Processes 
        {
            get { return _processes; }
        }

biznatchio
Mar 31, 2001


Buglord

notflipmo posted:

Am I entirely mistaken if I assume the above contains a typing error and should be like so:

Undoubtedly. The post textbox doesn't do compile checks. ;)

notflipmo
Feb 29, 2008
'

biznatchio posted:

Undoubtedly. The post textbox doesn't do compile checks. ;)
Came back to confirm my findings, my way compiles just fine :eng101:

Anyway, the serializing used above has improved the code for this project immensely.
readConfiguration() and writeConfiguration() have both been transformed to petite, understandable methods and to boot: I now have a Config class (that I really should have had anyway), that I can pass around and reference in a very readable way.

That class, in turn, can be scaled and changed to include new configuration options as the project grows.

All in all I'm entirely satisfied with what I learned today.

notflipmo fucked around with this message at 00:51 on Mar 26, 2008

wwb
Aug 17, 2004

A bit late for this party, but what you probably wanted to use are custom configuration sections rather than any funky XML Serialization. Not to say XML Serialization is not fun, easy nor cool. But for config, use the config stuff.

ray2k
Feb 7, 2004

Puppet scum beware!

wwb posted:

A bit late for this party, but what you probably wanted to use are custom configuration sections rather than any funky XML Serialization. Not to say XML Serialization is not fun, easy nor cool. But for config, use the config stuff.

Oh god, you went there.. Seriously, creating custom configuration sections with any marginally complicated schema can be such a complete pain in the rear end. I've done it and I'm not against using them, but it's not exactly a beginner topic. Although I will say that I discovered this that I've played with a bit and it does help when you're going the custom configuration route.

wwb
Aug 17, 2004

Honestly, I have not ran into too many issues creating complex configuration files. And I smokes the configuration crack hard. Furthermore, you can just use the same API to write the configuration values, so you don't even need to hand-write XML. Might not be the perfect tool for every job--such as when you have some legacy configuration that you want to pull in--but it should probably be the first pass.

PS: I should note that I am talking about the improved configuration options in 2.0, not the craptastic stuff in 1.1.

gibbed
Apr 10, 2006

I'm having some trouble getting the XmlSerializer to do the above situation:

code:
public struct VersionEntry // tried class too, but prefer it as a struct
{
	[XmlElement("name")]
	public string Name;

	[XmlElement("hash")]
	public string Hash;
}

[XmlRoot(ElementName = "versions")]
public class VersionTable
{
	[XmlElement("version", typeof(VersionEntry))]
	public List<VersionEntry> Versions;
}
When I deserialize the file, the list ends up with the correct number of items (Count == 13) but none of the items actually have loaded data.

Am I doing something wrong that I'm not realizing?

Edit: hahaha, of course after I post I realize my problem, I put XmlElement instead of XmlAttribute :doh:

gibbed fucked around with this message at 07:15 on Mar 26, 2008

dwazegek
Feb 11, 2005

WE CAN USE THIS :byodood:
I've been screwing around with LinqToSql, but I can't seem to get it to behave as I want it to.
I have the following classes:
code:
class Trigger
{
  Guid ID //primary key
  string Name
  List<Action> Actions //or some other collection
  Schedule schedule
}

class Action
{
  Guid TriggerID //PK
  int SequenceNr //PK
  Schedule schedule
  //other stuff
}

class Schedule
{
  Guid ScheduleID //PK
  //some other stuff
}
When I retrieve a Trigger from the database, I want its Schedule, its Actions and their individual Schedules to also be retrieved.

The Trigger will be retrieved and sent through web service calls.

I want both Trigger and Action to have a Schedule, but they shouldn't have exclusive ownership over it. The user can specify a bunch of schedules, and have multiple triggers or actions adhere to the same schedule.

I tried adding an one-to-one association between schedule and trigger, and between schedule and action, but a schedule seems to be tied to one trigger or action, and can't be shared between them. (Note: I don't mind if multiple copies of the same schedule are created, i.e. two actions with the same schedule don't have to references to the same instance of the schedule).

If I remove an action from a trigger, I want it to be deleted from the database. I have a one-to-many association between actions and triggers, and when I add an action it gets inserted, but if I remove an action it only gets removed from the trigger's action collection, not from the database, so the next time I retrieve the trigger, it still has the old actions. Is there anyway to automate this, or do I have to write my own code to do so?

dwazegek fucked around with this message at 10:37 on Mar 26, 2008

FinkieMcGee
May 23, 2001

Look, I have to go identify our dead father's body. I'm sorry you're having a bad drug experience, but deal with it.
Arighty, so an update on my caching post AND a question!

So I ended up modifying it so that we were actually using the ASP.NET caching instead of storing everything in a static dictionary. I also modified it so that all of the objects that were getting database selected on are now stored as Lists of that object in the database.

So now, I need to gain the same functionality in the list as I had with the database select (which is mostly there with the C# string library) except for one issue. When I do a "StartsWith" on letters, it's fine. When I try to do letters and maybe a number, it shits out and can't find a match. Is there any reason the string searches in C# can't match on numbers?

csammis
Aug 26, 2003

Mental Institution

FinkieMcGee posted:

Is there any reason the string searches in C# can't match on numbers?

No, because that's silly...show us this code and some example content, both working and not working. Something else must be wrong.

edit: You're not doing something like this, are you?
code:
if(str.StartsWith("abc" + (char)9))
Because that would be looking for "abc<tab>," the character that 9 corresponds to. You'd be wanting
code:
if(str.StartsWith(String.Format("abc{0}", 9)))
or
code:
int nine = 9;
if(str.StartsWith("abc" + nine.ToString()))

csammis fucked around with this message at 19:39 on Mar 26, 2008

FinkieMcGee
May 23, 2001

Look, I have to go identify our dead father's body. I'm sorry you're having a bad drug experience, but deal with it.
I mean, it's pretty simple, the filter variable is read from a search box:

code:
match.ObjStyle.Label.StartsWith(filter, StringComparison.OrdinalIgnoreCase)
Where filter is something like "G4", there are a couple of things that start with G4 in there.

csammis
Aug 26, 2003

Mental Institution

FinkieMcGee posted:

I mean, it's pretty simple, the filter variable is read from a search box:

code:
match.ObjStyle.Label.StartsWith(filter, [b]StringComparison.OrdinalIgnoreCase[/b])
Where filter is something like "G4", there are a couple of things that start with G4 in there.

The OrdinalIgnoreCase might be messing you up. It uses Unicode code point values, not ASCII, which may be leading to unexpected results. Try Invariant/CurrentCultureIgnoreCase.

FinkieMcGee
May 23, 2001

Look, I have to go identify our dead father's body. I'm sorry you're having a bad drug experience, but deal with it.
Ugh, I am stupid. I was searching for a something that didnt exist actually. Need more coffee.

whiskas
May 30, 2005
:siren: LINQ CHALLENGE :siren:

I have 2 tables. One called Classes, and another called Attendance.

Classes
--------
ClassID
ClassName

Attendance
-----------
AttendanceID
ClassID
FullName

If I wanted to get all the classes that have no attendees what would be the best way of doing this in a LINQ query?

All I can think of is some crazy foreach loop iterating over all the classes and running a query to check if it has any attendees. Surely there must be a better way of doing this.

Nevermind, figured the best way out:

Assume dc is my data context.

code:
var allclasseswithoutattendance = from c in dc.Classes
                                  where c.Attendance.Count( a => a.FullName != null) > 0
                                  select c;
I <3 LINQ

whiskas fucked around with this message at 21:04 on Mar 26, 2008

FinkieMcGee
May 23, 2001

Look, I have to go identify our dead father's body. I'm sorry you're having a bad drug experience, but deal with it.
Follwup question, hopefully not as stupid:

Is there anyway to easily ignore case using the Contains method like you can with startswith and endswith?

Edit: Other than not using ToUpper() on or both strings.

Fastbreak
Jul 4, 2002
Don't worry, I had ten bucks.
Quick question in visual studio.

We do alot of code reviews in my company and its a good thing too. We have a very fast pace environment with high turn around. We usually get a request from a client and have it out the door in 3 weeks. I am not talking simple stuff either.

Anyways, after a deploy to production (to meet client deadline) we then have a code review. We try to do it before, by time hardly ever allows it. After we make suggestions, we do another deploy in the next few days after the changes are done and it passes QA again.

The biggest thing by far that we find is people, including myself sometimes, forget to close datareaders or dispose certain objects, etc. Is there a way to customize VS to throw a warning if they aren't closed? Is there a custom snippet I can write in that would make it do this? A third party app? I have googled all over but I must not be using the right words. Anyone know of something like this?

FinkieMcGee
May 23, 2001

Look, I have to go identify our dead father's body. I'm sorry you're having a bad drug experience, but deal with it.

Fastbreak posted:

The biggest thing by far that we find is people, including myself sometimes, forget to close datareaders or dispose certain objects, etc. Is there a way to customize VS to throw a warning if they aren't closed? Is there a custom snippet I can write in that would make it do this? A third party app? I have googled all over but I must not be using the right words. Anyone know of something like this?

Why don't you just use Using statements to avoide the whole mess of closing/disposing? The only way I've found to realize that stuff is when stuff on the db end goes to hell.

csammis
Aug 26, 2003

Mental Institution

FinkieMcGee posted:

Follwup question, hopefully not as stupid:

Is there anyway to easily ignore case using the Contains method like you can with startswith and endswith?

Edit: Other than not using ToUpper() on or both strings.

Not generally, because Contains is implemented on collections of all types and not just collections of strings.

Options in this case: This wouldn't on sealed primitive types like strings, but for your own classes you could implement IComparable<T> and ignore case in your CompareTo implementation. If your collection supports a Contains or Find method that takes a Predicate<T>, you can write a predicate that ignores case in its comparison.

FinkieMcGee
May 23, 2001

Look, I have to go identify our dead father's body. I'm sorry you're having a bad drug experience, but deal with it.
Ah I see, that is unfortunate. I may implement it that way over time, but at the moment that's a bit too much hassle. I'll probably just ToLower() both strings and compare them that way. Thanks a lot for your help.

dwazegek
Feb 11, 2005

WE CAN USE THIS :byodood:

csammis posted:

Not generally, because Contains is implemented on collections of all types and not just collections of strings.
But string doesn't inherit Contains from any collections :confused:

Anyway, just call ToLowerInvariant (or ToUpperInvariant) on both the container and the containee.

edit:
I'm an idiot, Contains is part of IEnumerable<T>

edit2:
Well, string gets Contains(char) from IEnumerable<char>, but Contains(string) isn't part of any of string's interfaces.

edit3:
My inability to comprehend MSDN continues, Contains(char) isn't even part of IEnumerable, it's an extension method from System.Linq.

dwazegek fucked around with this message at 22:14 on Mar 26, 2008

Fastbreak
Jul 4, 2002
Don't worry, I had ten bucks.

FinkieMcGee posted:

Why don't you just use Using statements to avoide the whole mess of closing/disposing? The only way I've found to realize that stuff is when stuff on the db end goes to hell.

Some stuff doesn't implement idisposable. We also have a company internal framework with a custom class that I would like certain functions required to be called and throw an error if they are not.

Not possible?

dwazegek
Feb 11, 2005

WE CAN USE THIS :byodood:

Fastbreak posted:

Some stuff doesn't implement idisposable. We also have a company internal framework with a custom class that I would like certain functions required to be called and throw an error if they are not.

Not possible?
Most of the stuff concerning database connections is IDisposable, at least the connection classes and the DataReaders are, and possibly the DBCommand classes as well. Although at least a few of them only implicitly implement IDisposable.Dispose, so it doesn't show up in intellisense, but it does work just fine in using blocks.

As far as I know you can't generate warning when a method isn't called. One options might be to write a wrapper class around the classes that don't implement IDisposable and implement it yourself.

ray2k
Feb 7, 2004

Puppet scum beware!

Fastbreak posted:

Some stuff doesn't implement idisposable. We also have a company internal framework with a custom class that I would like certain functions required to be called and throw an error if they are not.

Not possible?

You could write a Visual Studio Addin that scans for those common scenarios and prevents a compile from passing if they are found. But it would be far more effort than, you know, remembering to actually dispose of things correctly the first time.

uXs
May 3, 2005

Mark it zero!

ray2k posted:

You could write a Visual Studio Addin that scans for those common scenarios and prevents a compile from passing if they are found. But it would be far more effort than, you know, remembering to actually dispose of things correctly the first time.

Can't you do this sort of thing in something like FxCop ? I've never used it or seen it closely, but I'm fairly sure it's a tool that can check code for compliance to all sorts of rules. Not closing connections seems like right up its alley. If you have a Team Foundation Server you could even make compliance required before you're allowed to check in code.

csammis
Aug 26, 2003

Mental Institution

uXs posted:

Can't you do this sort of thing in something like FxCop ? I've never used it or seen it closely, but I'm fairly sure it's a tool that can check code for compliance to all sorts of rules. Not closing connections seems like right up its alley. If you have a Team Foundation Server you could even make compliance required before you're allowed to check in code.

FxCop is indeed the poo poo, and I'm fairly sure this is the sort of thing it can detect. Here are some of the things it reports.

ray2k
Feb 7, 2004

Puppet scum beware!

uXs posted:

Can't you do this sort of thing in something like FxCop ? I've never used it or seen it closely, but I'm fairly sure it's a tool that can check code for compliance to all sorts of rules. Not closing connections seems like right up its alley. If you have a Team Foundation Server you could even make compliance required before you're allowed to check in code.

Never used FxCop, but after looking at this, it seems like it might be able to do the job, with a little work.

Fastbreak
Jul 4, 2002
Don't worry, I had ten bucks.

ray2k posted:

You could write a Visual Studio Addin that scans for those common scenarios and prevents a compile from passing if they are found. But it would be far more effort than, you know, remembering to actually dispose of things correctly the first time.

I will be sure to let me team know. Thanks.

But now back to stuff thats actually useful. I will recommend FXcop to some people. Everyone has there own little quarks of things they forget and this might help. I was speaking specifically to database objects either. There are certain functions for cleanup that we always want use in our custom framework.

I will try to read up more FXcop and see what we can do. Thanks guys.

csammis
Aug 26, 2003

Mental Institution
I'm just curious here:

Fastbreak posted:

There are certain functions for cleanup that we always want use in our custom framework.

If that's true, why aren't you implementing the Disposable pattern across your objects and calling those functions in Dispose() ? It'd certainly help consistency, if nothing else.

Fastbreak
Jul 4, 2002
Don't worry, I had ten bucks.

csammis posted:

I'm just curious here:


If that's true, why aren't you implementing the Disposable pattern across your objects and calling those functions in Dispose() ? It'd certainly help consistency, if nothing else.

Implementing Idisposable for these objects are on the list of things to do. Its right behind all the stuff that makes money so its never going to get done, sadly. I don't make the priorities, I just follow them.

csammis
Aug 26, 2003

Mental Institution

Fastbreak posted:

Implementing Idisposable for these objects are on the list of things to do. Its right behind all the stuff that makes money so its never going to get done, sadly. I don't make the priorities, I just follow them.

Oh, I know how that goes. The product I work on for my job is barreling towards market and I can't do half the refactors I want :smith:

Adbot
ADBOT LOVES YOU

Nurbs
Aug 31, 2001

Three fries short of a happy meal...Whacko!
I did something like this once but I don't really remember how:

I have a templateField in a gridview that I would like to display one field or the other depending on the particular data in the row.

Here's the code

code:
<asp:Label ID="Label1" runat="server" Text='<% if(Eval("userName").ToString().Equals("")) 
{ Eval("userName") } 
else { Eval("emailAddress") } %>'>
</asp:Label>
In the system I'm envisioning the user name is going to be an optional, but the email address is not. What I'd like to do is display the user name if they have one, but display the email address otherwise. Because some rows may match the condition and others don't I can't just set the column and forget about it.

Is my memory faulty or can this be done?

  • Locked thread