2

I have a grid, and I'm accessing each unique column via its name like so:

grid.Columns["SomeColumnA"]

However, I can only set the properties of that column if it is not null like so:

if (grid.Columns["SomeColumnB"] != null) {
    grid.Columns["SomeColumnB"].Width = 100;
}

I have about 15/20 different columns which need to be set for various things, but they all need to be checked for null first. It looks a bit messy as it's 15/20 if statements. I am wondering whether or not these if statements are the best way to do it, or if I can implement something else to simplify it and tidy the code up. Any ideas/suggestions?

Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
yigames
  • 185
  • 1
  • 5
  • 23
  • Why do you need to check if they are null at all? – Tim Schmelter Jan 07 '16 at 09:33
  • its a safety check, not sure if it will throw an exception if attempting to access a column if it doesn't exist, say if the column does not exist?? – yigames Jan 07 '16 at 11:19
  • If you try to use something that is `null` you always get a `NullReferenceException` at runtime. But as commented on my answer, normally grid-columns exist as separate objects which you can access directly(f.e. as `DataGridViewTexboxColumn`). On that way you keep readability with compile time safety. So if you for example have a column `SomeColumnA` then you can access it directly: `this.SomeColumnA.Width = 100`. No need to use `grid.Columns["SomeColumnA"]` and you can be sure that it's not null. – Tim Schmelter Jan 07 '16 at 11:21

4 Answers4

5

If you use C# 6.0, you can use the null propagation operator. So

if (grid.Columns["SomeColumnB"] != null) {
    grid.Columns["SomeColumnB"].Width = 100;
}

becomes

grid.Columns["SomeColumnB"]?.Width = 100;

Much cleaner.

Umut Seven
  • 398
  • 2
  • 11
  • 20
  • 1
    Does that actually compile? – Matthew Watson Jan 07 '16 at 09:49
  • Does this work? I have no C#6 but it seems that it can only be used to evaluate expressions not for assignments. Look at [this](http://stackoverflow.com/questions/32519200/c-sharp-6-0-null-propagation-operator-property-assignment), especially [this answer](http://stackoverflow.com/a/32519611/284240) suggests that it's not possible. – Tim Schmelter Jan 07 '16 at 09:49
  • 3
    I'm fairly sure this doesn't work. Error will be something like *"the left-hand side of an assignment must be a variable, property or indexer"* – Matthew Watson Jan 07 '16 at 09:51
  • @MatthewWatson: yes, that's what the [linked question](http://stackoverflow.com/questions/32519200/c-sharp-6-0-null-propagation-operator-property-assignment) also mentions. The null-propagation operator returns a nullable type for the case that anything on the road was null. – Tim Schmelter Jan 07 '16 at 09:53
  • no it doesn't work but its something for c#7 hopefully. – yigames Jan 07 '16 at 09:54
  • 1
    However even this WOULD compile OP still has to do all those checks manually. Tims solution should work best. – MakePeaceGreatAgain Jan 07 '16 at 09:54
  • Interestingly, if the property setter can be treated as a method (which in fact it is), then the above would work, e.g. `grid.Columns["SomeColumnB"]?.set_Width(100);` – Ivan Stoev Jan 07 '16 at 10:04
  • @IvanStoev: again, i cannot test it, but does that work? I thought this operator always returns a value(not a variable) and cannot be used to do an assignment or to call a method. – Tim Schmelter Jan 07 '16 at 10:14
  • I havent tested it with a grid, but as null propogation works with dictionaries & arrays, I don't see why it wouldn't work here. – Umut Seven Jan 07 '16 at 10:18
  • @TimSchmelter Probably I didn't state it clear, it **doesn't** work because C# does not allow using the "explicit" `get_`/`set_` method call. My point was that fundamentally there should not be a problem (I guess). But you **can** use that syntax to make a method call - it's used for optionally invoking event handlers for instance. – Ivan Stoev Jan 07 '16 at 10:27
  • @IvanStoev: that's what i wanted to know, if you can use the operator to do method calls. – Tim Schmelter Jan 07 '16 at 10:54
4

I don't understand why those grid-columns can be null at all. However, maybe you could store the column names in a separate collection and use code like following:

string[] columns = { "SomeColumnA", "SomeColumnB", "SomeColumnC" };
var gridColumns = columns.Select(c => grid.Columns[c]).Where(c => c != null);

foreach (var col in gridColumns)
{
    // you could use a switch if you need to set different things according to the Name
    switch (col.Name)
    {
        case "SomeColumnA": col.Width = 100; break;
        case "SomeColumnB": col.Width = 120; break;
        case "SomeColumnC": col.Width = 150; break;
        default: break;
    }
}
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Or just `foreach (var col in grid.Columns)` if the OP wants to process ALL the columns (assuming it works for the actual types) – Matthew Watson Jan 07 '16 at 10:01
  • @MatthewWatson: of course, but i assume that OP uses the column-names for some reason and that there's also a reason why they can be null sometimes. Normally grid-columns even exist as separate objects which you can access directly(f.e. as `DataGridViewTexboxColumn`). On that way you keep readability with compile time safety. – Tim Schmelter Jan 07 '16 at 10:04
  • Yes, I agree with that. – Matthew Watson Jan 07 '16 at 10:13
2

You can use a loop through all the columns like this

foreach(var column in grid.Columns)
{
    //do something to the column
}
Cheng Chen
  • 42,509
  • 16
  • 113
  • 174
0

Why not have a function to set a property of a control ?

void SetProperty(Control ctrl,int value,string columnName)
{
    if(ctrl!=null) ctrl.Columns[columnName].Width=value; 
}

You can also have other operations or have optional parameters in the function signature depending on how many properties you want to set.