views:

96

answers:

2

While I userstand how get; & set; with simple types such as strings now can more properties like Dictionary be get or set or can they?

I have a small dos programe trying to do this. snippet below.

# User.cs
namespace LDIFMod
{
    public class User
    {

        public string UserHash { get; set; }
        public string UserID { get; set; }
        public Dictionary<string, string> UserDict { get; set; }  <- how to do this???
}

}

and in my Program.cs

var query = from line in File.ReadAllLines(args[0])
let UserRecord = line.Split(',')
select new User()

{

 UserHash = UserRecord[2].Trim() +UserRecord[3].Trim(),
 UserID = UserRecord[4].Trim(),
 UserDict.????   // userDict should contain key = UserRecord[5] & value = UserRecord[9]

}
+1  A: 

You can use the collection initializer to create the dictionary:

{
    UserHash = UserRecord[2].Trim() +UserRecord[3].Trim(),
    UserID = UserRecord[4].Trim(),
    UserDict = new Dictionary<string, string> { { UserRecord[5],  UserRecord[9] } }
}

Also, see here: http://msdn.microsoft.com/en-us/library/bb531208.aspx

Etienne de Martel
This isn't wrong, but it's probably not right for your needs. I expect you want to get and set dictionary values, not replace the dictionary with a new one. See Scott Chamberlain's answer for how to do that.
Steven Sudit
Indeed. I upvoted his answer as well.
Etienne de Martel
+2  A: 

You will need to first initialize the dictionary in the constructor of the user class. Use the private set to prevent people from re-initializing the dictionary.

# User.cs
namespace LDIFMod
{
    public class User
    {
        User()
        {
            UserDict = new Dictionary<string, string>()
        }
        public string UserHash { get; set; }
        public string UserID { get; set; }
        public Dictionary<string, string> UserDict { get; private set; }
    }
}

Your calling code becomes

var query = from line in File.ReadAllLines(args[0])
let UserRecord = line.Split(',')
select new User()
{
     UserHash = UserRecord[2].Trim() +UserRecord[3].Trim(),
     UserID = UserRecord[4].Trim(),
     UserDict.Add(UserRecord[5],UserRecord[9]);
}

This returns one dictionary per query row. if you want all of the rows to share a dictionary you will need to make it static or not store it inside User. If you do this be aware that linq is delayed execution so the dictionary will not be fully populated until after you fully enumerate the query.


I thought I would give a example of how to do it with all of them in a single dictionary.

# User.cs
namespace LDIFMod
{
    public class User
    {
        public string UserHash { get; set; }
        public string UserID { get; set; }
        public readonly string[] SourceData {get; private set;}
    }
}

and here is the query

var query = from line in File.ReadAllLines(args[0])
let UserRecord = line.Split(',')
select new User()
{   
     UserHash = UserRecord[2].Trim() + UserRecord[3].Trim(),
     UserID = UserRecord[4].Trim(),
     SourceData = UserRecord;
}
var UserLookp = query.ToDictionary((user) => user.SourceData[5], (user) => user.SourceData[9]);

This is purely from memory without a ide to check for bugs so there could be some errors.

Scott Chamberlain
This is the right idea. The only thing I'd add is that, if there's just one dictionary or if one of them is clearly the main dictionary, perhaps this class could benefit from wrapping it in an indexer.
Steven Sudit
I made the changes you suggested but alas adding " UserDict.Add(UserRecord[5],UserRecord[9]);" to the calling code does not appear to be valid and it wont compile.
Canacourse
Use Etienne de Martel's version of the line `UserDict = new Dictionary<string, string> { { UserRecord[5], UserRecord[9] } }` and get rid of the constructor I added, that should work, but I don't think it will give you the results you are hoping for.
Scott Chamberlain