Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Code cleanup in System.ComponentModel.TypeConverter#14154

Merged
stephentoub merged 17 commits intodotnet:masterfrom
bmeverett:code-cleanup
Dec 9, 2016
Merged

Code cleanup in System.ComponentModel.TypeConverter#14154
stephentoub merged 17 commits intodotnet:masterfrom
bmeverett:code-cleanup

Conversation

@bmeverett
Copy link
Copy Markdown

@bmeverett bmeverett commented Dec 1, 2016

Resolves #12160 to clean up code in System.ComponentModel.TypeConverter
cc @AlexGhiondea

  • Remove explicit base() from constructor calls
  • Replace explicitly implemented properties with auto-implemented properties when possible
  • Simplify members and properties with 1 lines of code to expression bodied members
  • Switch over to the ?. operator in C# for null checking
  • Switch to string interpolation instead of string concatenation
  • Remove unnecessary initialization (ie. Bool foo = false)
  • Replace empty arrays with Array.Empty()
  • Replace string literals with nameof wherever possible.
  • Simplify event handler declarations when no custom code is required
  • Introduce readonly modifier for sync objects.
  • Replace nongeneric collections with generic collections
  • Use foreach instead of manually writing the foreach logic.
  • Cache the char[] into a static readonly field (ie. new char[] { '' })
  • Simplify the CultureInfoMapper code

I created an individual commit for each improvement, didn't know if that would make review any easier. I tried to search the project and make sure everything was accounted for. This is a decent size project so something may have been missed. Feel free to comment and I'll be glad to fix it.

@dnfclas
Copy link
Copy Markdown

dnfclas commented Dec 1, 2016

Hi @bmeverett, I'm your friendly neighborhood .NET Foundation Pull Request Bot (You can call me DNFBOT). Thanks for your contribution!

In order for us to evaluate and accept your PR, we ask that you sign a contribution license agreement. It's all electronic and will take just minutes. I promise there's no faxing. https://cla2.dotnetfoundation.org.

TTYL, DNFBOT;

@dnfclas
Copy link
Copy Markdown

dnfclas commented Dec 1, 2016

@bmeverett, Thanks for signing the contribution license agreement so quickly! Actual humans will now validate the agreement and then evaluate the PR.

Thanks, DNFBOT;

@AlexGhiondea
Copy link
Copy Markdown
Contributor

@bmeverett thanks for your contribution! I am going to take a closer look at this next week when I get back in the office!

//

Attribute[] attributes = null;
Attribute[] attributes = Array.Empty<Attribute>();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be assigned at all? It's set in both the subsequent if/else branch, so it should be definitely assigned without needing this initializer.

_onListChanged -= value;
}
}
public event ListChangedEventHandler ListChanged;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look like a safe change. The _onListChanged field was annotated as [NonSerialized], but the backing field generated for this event won't have such an attribute on it.

_dataSource = null;
_dataMember = null;
DataSource = null;
DataMember = null;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these lines necessary at all? null is the default value.

_dataSource = dataSource;
_dataMember = null;
DataSource = dataSource;
DataMember = null;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this line necessary? null is the default value.

foreach (var val in GetStandardValues(context))
{
CultureInfo info = (CultureInfo)e.Current;
CultureInfo info = (CultureInfo)val;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be changed to just:

foreach (CultureInfo info in GetStandardValues(context))

foreach (var val in _values)
{
CultureInfo info = (CultureInfo)e.Current;
CultureInfo info = (CultureInfo)val;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

else
{
format = formatInfo.ShortDatePattern + " " + formatInfo.ShortTimePattern;
format = $"{formatInfo.ShortDatePattern} {formatInfo.ShortTimePattern}";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be reverted. It's less expensive the way it was originally.

get
{
// ComCtl32.dll V6 (WindowsXP) provides a nice black circle but we don't want to attempt to simulate it
// here to avoid hard coding values. MaskedTextBox picks up the right value at run time from comctl32.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this comment deleted?

_nameHash = _name.GetHashCode();

ArrayList newArray = new ArrayList();
List<Attribute> newArray = new List<Attribute>();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: extra space before the =

}

return obj;
return obj ?? (obj = Activator.CreateInstance(objectType, args));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does obj need to be assigned? e.g. why not just:

return obj ?? Activator.CreateInstance(objectType, args);

?

}

return instance;
return instance ?? (instance = NodeFor(objectType).CreateInstance(provider, objectType, argTypes, args));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does instance need to be assigned?

Copy link
Copy Markdown
Member

@stephentoub stephentoub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Overall the changes look good, but there are some issues that will need to be addressed.

@bmeverett
Copy link
Copy Markdown
Author

@stephentoub Thanks for the feedback! Especially about string interpolation. I will keep that in mind. I will fix up your comments and make another commit.

Copy link
Copy Markdown
Contributor

@AlexGhiondea AlexGhiondea left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all this work @bmeverett!!!

Overall it looks great! I had a couple of minor comments that we should consider doing before taking this change.

Again -- thanks for doing this!!

return typeof(Byte);
}
}
internal override Type TargetType => typeof(Byte);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Byte -> byte

{
return s_cultureInfoNameMap[cultureInfoDisplayName];
}
private static readonly Dictionary<string, string> s_cultureInfoNameMap = CreateMap();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was the removal of volatile intentional?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used the example from the issue and you had it removed there. Should it be added back in?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this change, volatile isn't necessary anymore... it's almost the opposite of readonly, where readonly effectively says "this will never change so feel free to cache it as long as you like" and volatile kind of says "this can change at any moment and it's important you use the absolute latest".

return typeof(Decimal);
}
}
internal override Type TargetType => typeof(Decimal);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decimal -> decimal

public DefaultBindingPropertyAttribute()
{
_name = null;
Name = null;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not required

return _name;
}
}
public string Name => _name;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove _name?

return typeof(SByte);
}
}
internal override Type TargetType => typeof(SByte);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SByte -> sbyte

return typeof(Single);
}
}
internal override Type TargetType => typeof(Single);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single -> float

return typeof(UInt16);
}
}
internal override Type TargetType => typeof(UInt16);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uint16 -> ushort

return typeof(UInt32);
}
}
internal override Type TargetType => typeof(UInt32);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UInt32- > uint

return typeof(UInt64);
}
}
internal override Type TargetType => typeof(UInt64);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UInt64 -> ulong

Copy link
Copy Markdown
Member

@safern safern left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some comments.

Thanks for doing this!

private class Site : ISite
{
private IComponent _component;
private Container _container;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Just such as you did it with _component we should delete _container and just use the property Container with it's default get.

return _commandID;
}
}
public virtual int ID => _commandID;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we here not using the same approach as in the other classes that you deleted the private fields and used the property only with a public get?

return _oldDesigner;
}
}
public IDesignerHost OldDesigner => _oldDesigner;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, can we remove _oldDesigner and _newDesigner?

return invalidIndex;
}
}
public static int InvalidIndex => invalidIndex;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we update all constants from this class to be uppercase? e.g invalidIndex to INVALID_INDEX ?

return _container;
}
}
public IContainer Container => _container;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we delete _container and just use Container ?

@@ -69,49 +67,27 @@ public ToolboxItemFilterAttribute(string filterString, ToolboxItemFilterType fil
{
if (filterString == null) filterString = String.Empty;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of doing

if (filterString == null) filterString = String.Empty

we could simplify this to one line when initializing FilterString :

FilterString = filterString ?? string.Empty;

}
else
{
return site.Name;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could simplify this to:

return nestedSite != null ? nestedSite.FullName : site.Name;

Or I think we could use ?? operator as well:

return (nestedSite?.FullName) ?? site.Name;

@karelz karelz modified the milestone: 1.2.0 Dec 6, 2016
converted remaining properties to auto properties
@bmeverett
Copy link
Copy Markdown
Author

I think the tests may have gotten stuck. Not sure if it was something I did.

@safern
Copy link
Copy Markdown
Member

safern commented Dec 7, 2016

The details of Innerloop CentOS7.1 are not found on the link provided.
Innerloop OSX Debug has an error, I'm taking a look on that one.
Innerloop OSX Release actually passed but never updated the status here on the PR.

@mmitche

@mmitche
Copy link
Copy Markdown
Member

mmitche commented Dec 7, 2016

@safern I beleive this is because the lab is being moved. Please ignore.

@safern
Copy link
Copy Markdown
Member

safern commented Dec 7, 2016

Ok then I'm going to go ahead and restart both tests with failures.

test Innerloop CentOS7.1 Debug Build and Test please
test Innerloop OSX Debug Build and Test please

Copy link
Copy Markdown
Member

@safern safern left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! Thanks for doing this.

@stephentoub
Copy link
Copy Markdown
Member

@dotnet-bot test this please

Copy link
Copy Markdown
Member

@stephentoub stephentoub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @bmeverett!

@stephentoub stephentoub merged commit 6f48f19 into dotnet:master Dec 9, 2016
@bmeverett
Copy link
Copy Markdown
Author

Thanks guys!

@bmeverett bmeverett deleted the code-cleanup branch December 9, 2016 15:53
steveharter pushed a commit to steveharter/dotnet_corefx that referenced this pull request Dec 19, 2016
* remove explicit base calls

* auto implemented properties

* use expression body members

* use ? for null checking

* use string interpolation

* remove unnecessary initialization

* replace empty arrays with array.empty

* simplify event handler declarations

* readonly modifier for sync objects

* use foreach

* cache char[] into static readonly field

* simplify CultureInfoMapper

* reaplce non generic collections with generic collections

* fix code review comments a lot dealing with string interpolation.

* add space to datetimeconverter and datetimeoffsetconverter to fix tests

* additional modifications converting  types

* uppercase constants in MaskedTextProvider
converted remaining properties to auto properties
pjanotti pushed a commit to pjanotti/corefx that referenced this pull request Sep 28, 2017
pjanotti pushed a commit that referenced this pull request Sep 28, 2017
poizan42 added a commit to poizan42/corefx that referenced this pull request Oct 3, 2017
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
)

* remove explicit base calls

* auto implemented properties

* use expression body members

* use ? for null checking

* use string interpolation

* remove unnecessary initialization

* replace empty arrays with array.empty

* simplify event handler declarations

* readonly modifier for sync objects

* use foreach

* cache char[] into static readonly field

* simplify CultureInfoMapper

* reaplce non generic collections with generic collections

* fix code review comments a lot dealing with string interpolation.

* add space to datetimeconverter and datetimeoffsetconverter to fix tests

* additional modifications converting  types

* uppercase constants in MaskedTextProvider
converted remaining properties to auto properties


Commit migrated from dotnet/corefx@6f48f19
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Code cleanup for System.ComponentModel.TypeConverter

7 participants