HiveBrain v1.2.0
Get Started
← Back to all entries
debugcsharpMinor

AppVersion Struct & VersionParse Exception

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
appversionstructversionparseexception

Problem

I am working on an app that will interact with assembly (app) versions. I created a struct for that, along with an exception for parsing error.

Here's the code:

```
[Serializable]
public class VersionParseException : Exception
{
public VersionParseException()
{ }

public VersionParseException(string message)
: base(message)
{ }

public VersionParseException(string message, Exception innerException)
: base(message, innerException)
{ }

protected VersionParseException(SerializationInfo info, StreamingContext context)
: base(info, context)
{ }

}

public struct AppVersion
{
int _majorVersion;
public int MajorVersion
{
get { return _majorVersion; }
set
{
_majorVersion = value;
}
}

int _minorVersion;
public int MinorVersion
{
get { return _minorVersion; }
set
{
_minorVersion = value;
}
}

int _buildNumber;
public int BuildNumber
{
get { return _buildNumber; }
set
{
_buildNumber = value;
}
}

int _revision;
public int Revision
{
get { return _revision; }
set
{
_revision = value;
}
}

public string Version
{
get { return MajorVersion.ToString() + "." + MinorVersion.ToString() + "." + BuildNumber.ToString() + "." + Revision.ToString(); }
set
{
try
{
MajorVersion = int.Parse(value.Split('.')[0]);
MinorVersion = int.Parse(value.Split('.')[1]);
BuildNumber = int.Parse(value.Split('.')[2]);
Revision = int.Parse(value.Sp

Solution

I am working on an app that will interact with assembly (app) versions

There's a class, System.Version, that might be suitable for your needs. System.Version:


Represents the version number of an assembly, operating system, or the common language runtime.

It has Major, Minor, Build, and Revision properties.

If you still want to roll your own, my advice is to

  • Make AppVersion immutable



  • Be stricter about the values you allow



  • Implement IEquatable



  • Consider implementing IComparable



In general, you should avoid mutable structs.

From MSDN


X DO NOT define mutable value types.


Mutable value types have several problems. For example, when a property getter returns a value type, the caller receives a copy. Because the copy is created implicitly, developers might not be aware that they are mutating the copy, and not the original value.

See also: Why are mutable structs “evil”?

With the code as written, this works just fine:

appVersion.Version = "   +123 . -4236 . +0 . -789";


Use the overloads of int.Parse/int.TryParse that take a NumberStyles argument. If you provide constructors as suggested below, check that the values passed in are non-negative.

From MSDN


✓ DO implement IEquatable on value types.


The Object.Equals method on value types causes boxing, and its default implementation is not very efficient, because it uses reflection. Equals can have much better performance and can be implemented so that it will not cause boxing.

I find it hard to imagine not ever wanting to compare app versions, so you will probably want to implement IComparable.

I would recommending getting rid of the Version property entirely. Instead, provide one or more constructors like

public AppVersion(int majorVersion, int minorVersion)

public AppVersion(int majorVersion, int minorVersion, int buildNumber)

...


and then provide static methods AppVersion Parse(string) and bool TryParse(string, out AppVersion).

Also, you should be aware of the existence of auto-implemented properties.

Code Snippets

appVersion.Version = "   +123 . -4236 . +0 . -789";
public AppVersion(int majorVersion, int minorVersion)

public AppVersion(int majorVersion, int minorVersion, int buildNumber)

...

Context

StackExchange Code Review Q#110825, answer score: 5

Revisions (0)

No revisions yet.