String whitespacesUnit-testing the importing of data into a databaseIn-memory cache implementation revisitedRolling my own Configuration with UISimple and reusable system for user registration and tracking and auto-updatesMVVM: Am I doing it right?Alternative to the Josh Bloch Builder pattern in C#Singleton with readonly parametersVBA Text Class, sort of like .NETWeb-app for tracking containers
Why is a road bike faster than a city bike with the same effort? How much faster it can be?
Help in drawing resonance structures in case of polybasic acids
Whaling ship logistics
Why does my browser attempt to download pages from http://clhs.lisp.se instead of viewing them normally?
Is it ok if I haven't decided my research topic when I first meet with a potential phd advisor?
Why is STARTTLS still used?
Why did UK NHS pay for homeopathic treatments?
Clear text passwords in Unix
Beyond Futuristic Technology for an Alien Warship?
Is it acceptable to say that a reviewer's concern is not going to be addressed because then the paper would be too long?
Diminutive -ula
Why did the Soviet Union not "grant" Inner Mongolia to Mongolia after World War Two?
Algorithm that generates orthogonal vectors: C++ implementation
What should I consider when deciding whether to delay an exam?
Is the iPhone's eSim for the home or roaming carrier?
Practicality of 30 year fixed mortgage at 55 years of age
Why is volatility skew/smile for long term options flatter compare to short term options?
String whitespaces
Difference between "rip up" and "rip down"
When does a Sea Sorcerer choose to use Curse of the Sea's additional effect?
There are 51 natural numbers between 1-100, proof that there are 2 numbers such that the difference between them equals to 5
If a spaceship ran out of fuel somewhere in space between Earth and Mars, does it slowly drift off to the Sun?
My manager quit. Should I agree to defer wage increase to accommodate budget concerns?
Should the average user with no special access rights be worried about SMS-based 2FA being theoretically interceptable?
String whitespaces
Unit-testing the importing of data into a databaseIn-memory cache implementation revisitedRolling my own Configuration with UISimple and reusable system for user registration and tracking and auto-updatesMVVM: Am I doing it right?Alternative to the Josh Bloch Builder pattern in C#Singleton with readonly parametersVBA Text Class, sort of like .NETWeb-app for tracking containers
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
$begingroup$
Here is a shortest possible syntax for replacing whitespaces with null
and throwing an exception where it is not allowed:
public class Name
string _first;
public string First
get => _first;
set => _first = (Optional)value;
string _middle;
public string Middle
get => _middle;
set => _middle = (Required)value;
Where:
public class Optional
public static explicit operator Optional(string text) => new Optional(text);
public static implicit operator string(Optional optional) => optional.Text;
Optional(string text) => Text = IsNullOrWhiteSpace(text) ? null : text;
string Text get;
And:
public class Required
public static explicit operator Required(string text) => new Required((Optional)text);
public static implicit operator string(Required required) => required.Text;
Required(string text) => Text = text ?? throw new FormatException();
string Text get;
P.S. Value modification on property assignment is not recommended, but could be very handy sometimes :)
Reasoning Update
@visualmelon I did it to have a chance to say the following: 😊
I do assume that OOD and a scalable language paradigm
is the only way to keep high morale of the software development process. Seriously, the price of not knowing the default visibility of a class API member is tremendous. Damn, people, learn it and stop this ongoing customer robbery. This industry is ruined by cheap labor, the believe that everybody could code and that excessive usage of POCO could substitute basic understanding of the OOD principals, but it is wrong. One need a totally screwed economic environment to reason on this stuff positively. (My current project has 80% code redundancy! Start using ValueObjects, switch to Event Sourcing and all those left hand-right hand excessive assignments will be gone with the wind reducing the cost of support tremendously…)
Static functions vs custom types: static functions require extra “using static” directive while classes are not. And I do believe that it is totally OK to have a concept of Optional and Required string to be captured as classes in, let’s say, text processing domain. It could sound out of context somewhere else, but domain namespaces do matter… I would use different exception type, different names instead of Optional
and Required
in the different wider context, something like (NullIfWhitespace)text
and (ThrowIfWhitespace)text
.
P.S. Cracking software interviews
book suggest to do not mention .NET experience while being interviewed for a non C# position. I am personally is just ashamed but understood the reason. We should be more open to gaining efficiency everywhere we could.
c# strings null
$endgroup$
add a comment
|
$begingroup$
Here is a shortest possible syntax for replacing whitespaces with null
and throwing an exception where it is not allowed:
public class Name
string _first;
public string First
get => _first;
set => _first = (Optional)value;
string _middle;
public string Middle
get => _middle;
set => _middle = (Required)value;
Where:
public class Optional
public static explicit operator Optional(string text) => new Optional(text);
public static implicit operator string(Optional optional) => optional.Text;
Optional(string text) => Text = IsNullOrWhiteSpace(text) ? null : text;
string Text get;
And:
public class Required
public static explicit operator Required(string text) => new Required((Optional)text);
public static implicit operator string(Required required) => required.Text;
Required(string text) => Text = text ?? throw new FormatException();
string Text get;
P.S. Value modification on property assignment is not recommended, but could be very handy sometimes :)
Reasoning Update
@visualmelon I did it to have a chance to say the following: 😊
I do assume that OOD and a scalable language paradigm
is the only way to keep high morale of the software development process. Seriously, the price of not knowing the default visibility of a class API member is tremendous. Damn, people, learn it and stop this ongoing customer robbery. This industry is ruined by cheap labor, the believe that everybody could code and that excessive usage of POCO could substitute basic understanding of the OOD principals, but it is wrong. One need a totally screwed economic environment to reason on this stuff positively. (My current project has 80% code redundancy! Start using ValueObjects, switch to Event Sourcing and all those left hand-right hand excessive assignments will be gone with the wind reducing the cost of support tremendously…)
Static functions vs custom types: static functions require extra “using static” directive while classes are not. And I do believe that it is totally OK to have a concept of Optional and Required string to be captured as classes in, let’s say, text processing domain. It could sound out of context somewhere else, but domain namespaces do matter… I would use different exception type, different names instead of Optional
and Required
in the different wider context, something like (NullIfWhitespace)text
and (ThrowIfWhitespace)text
.
P.S. Cracking software interviews
book suggest to do not mention .NET experience while being interviewed for a non C# position. I am personally is just ashamed but understood the reason. We should be more open to gaining efficiency everywhere we could.
c# strings null
$endgroup$
add a comment
|
$begingroup$
Here is a shortest possible syntax for replacing whitespaces with null
and throwing an exception where it is not allowed:
public class Name
string _first;
public string First
get => _first;
set => _first = (Optional)value;
string _middle;
public string Middle
get => _middle;
set => _middle = (Required)value;
Where:
public class Optional
public static explicit operator Optional(string text) => new Optional(text);
public static implicit operator string(Optional optional) => optional.Text;
Optional(string text) => Text = IsNullOrWhiteSpace(text) ? null : text;
string Text get;
And:
public class Required
public static explicit operator Required(string text) => new Required((Optional)text);
public static implicit operator string(Required required) => required.Text;
Required(string text) => Text = text ?? throw new FormatException();
string Text get;
P.S. Value modification on property assignment is not recommended, but could be very handy sometimes :)
Reasoning Update
@visualmelon I did it to have a chance to say the following: 😊
I do assume that OOD and a scalable language paradigm
is the only way to keep high morale of the software development process. Seriously, the price of not knowing the default visibility of a class API member is tremendous. Damn, people, learn it and stop this ongoing customer robbery. This industry is ruined by cheap labor, the believe that everybody could code and that excessive usage of POCO could substitute basic understanding of the OOD principals, but it is wrong. One need a totally screwed economic environment to reason on this stuff positively. (My current project has 80% code redundancy! Start using ValueObjects, switch to Event Sourcing and all those left hand-right hand excessive assignments will be gone with the wind reducing the cost of support tremendously…)
Static functions vs custom types: static functions require extra “using static” directive while classes are not. And I do believe that it is totally OK to have a concept of Optional and Required string to be captured as classes in, let’s say, text processing domain. It could sound out of context somewhere else, but domain namespaces do matter… I would use different exception type, different names instead of Optional
and Required
in the different wider context, something like (NullIfWhitespace)text
and (ThrowIfWhitespace)text
.
P.S. Cracking software interviews
book suggest to do not mention .NET experience while being interviewed for a non C# position. I am personally is just ashamed but understood the reason. We should be more open to gaining efficiency everywhere we could.
c# strings null
$endgroup$
Here is a shortest possible syntax for replacing whitespaces with null
and throwing an exception where it is not allowed:
public class Name
string _first;
public string First
get => _first;
set => _first = (Optional)value;
string _middle;
public string Middle
get => _middle;
set => _middle = (Required)value;
Where:
public class Optional
public static explicit operator Optional(string text) => new Optional(text);
public static implicit operator string(Optional optional) => optional.Text;
Optional(string text) => Text = IsNullOrWhiteSpace(text) ? null : text;
string Text get;
And:
public class Required
public static explicit operator Required(string text) => new Required((Optional)text);
public static implicit operator string(Required required) => required.Text;
Required(string text) => Text = text ?? throw new FormatException();
string Text get;
P.S. Value modification on property assignment is not recommended, but could be very handy sometimes :)
Reasoning Update
@visualmelon I did it to have a chance to say the following: 😊
I do assume that OOD and a scalable language paradigm
is the only way to keep high morale of the software development process. Seriously, the price of not knowing the default visibility of a class API member is tremendous. Damn, people, learn it and stop this ongoing customer robbery. This industry is ruined by cheap labor, the believe that everybody could code and that excessive usage of POCO could substitute basic understanding of the OOD principals, but it is wrong. One need a totally screwed economic environment to reason on this stuff positively. (My current project has 80% code redundancy! Start using ValueObjects, switch to Event Sourcing and all those left hand-right hand excessive assignments will be gone with the wind reducing the cost of support tremendously…)
Static functions vs custom types: static functions require extra “using static” directive while classes are not. And I do believe that it is totally OK to have a concept of Optional and Required string to be captured as classes in, let’s say, text processing domain. It could sound out of context somewhere else, but domain namespaces do matter… I would use different exception type, different names instead of Optional
and Required
in the different wider context, something like (NullIfWhitespace)text
and (ThrowIfWhitespace)text
.
P.S. Cracking software interviews
book suggest to do not mention .NET experience while being interviewed for a non C# position. I am personally is just ashamed but understood the reason. We should be more open to gaining efficiency everywhere we could.
c# strings null
c# strings null
edited 3 hours ago
Dmitry Nogin
asked 8 hours ago
Dmitry NoginDmitry Nogin
3,2691 gold badge10 silver badges31 bronze badges
3,2691 gold badge10 silver badges31 bronze badges
add a comment
|
add a comment
|
2 Answers
2
active
oldest
votes
$begingroup$
Not sure that adding a 7-line validator class per validation rule (plus typecasting abuse) is any shorter/better than a set of more straightforward composable validating one-liners, something like:
public static class ValidatingTransformers
public static T ThrowsIfNull<T>(this T s, string msg = "") =>
s != null ? s : throw new ArgumentException(msg);
public static string ThrowsIfEmpty(this string s, string msg = "") =>
!string.IsNullOrWhiteSpace(s) ? s : throw new ArgumentException(msg);
public static string EmptyIfNull(this string s) => s ?? "";
public static string NullIfEmpty(this string s) => !string.IsNullOrWhiteSpace(s) ? s : null;
... et cetera
Some other thoughts:
- Replacing empty/whitespace strings with
null
does not look like a great idea to me. Because, well, thenull
and theNullReferenceException
. An empty string looks like a safer alternative. - I'd avoid property setters and mutating a state, even if setters protect invariants. Much simpler, shorter, and safer alternative:
public class Name
public string First get;
public string Middle get;
public string Last get;
public Name(string first, string middle, string last)
First = first.NullIfEmpty();
Middle = middle.ThrowsIfNull("middle name must not be null");
Last = last.ThrowsIfEmpty("last name must not be empty");
Shorter code, one single place for all validations, never ever get an object in an inconsistent state, no issues with concurrent mutations.
New contributor
$endgroup$
$begingroup$
+1, yes - I used extension methods before. The problem is - invoking a method on the null reference makes my feeling scream a way more than a type cast. Would it still be a typecasting abuse for you if relevant model names be used, like(Text)str
or(TextOrNull)str
for the same purposes?
$endgroup$
– Dmitry Nogin
19 mins ago
$begingroup$
Type cast exception will look reasonable then for(Text)
as no white spaces are allowed for the type.
$endgroup$
– Dmitry Nogin
15 mins ago
add a comment
|
$begingroup$
Edit: the tone of this might seem a bit negative, so I'll add that this was a fun one to review in hopes of lightening the mood ;)
Miscellaneous thoughts:
This is horrifying! Why did you do this?!
You can just about get away with this for properties, but for method calls with required/optional fields, a
FormatException
will be inadequate (anArgumentException
telling the caller which argument went wrong is important), which rather limits the scope of this technique.Because the thing is type specific, you could give it a sensible name (e.g.
OptionalString
), make both conversions implicit, and use it as the field type. This would required even less syntax, and would be somewhat less opaque to the maintainer who has to live with this.These need documentation: it's not obvious that an
Optional
should convert""
tonull
: this is enough to put me off it completely.You can get this 'low-char-count syntax by using a
static using
and providing these as static methods to a static class. The advantages would include:- It's not horrifying
- It requires less code, because you don't have to build a whole type and its conversions for each sort of string
- You can't misuse the types in ways you didn't intend, and they don't appear everywhere
- You can throw the static methods at a delegate if you have need
- It's not horrifying
- People who don't hate themselves can use the fully qualified name
- It won't incur an allocation every time you assign a value (though using
struct
s would address this already) - You have greater freedom with the type of checks you can perform (e.g. multiple parameters)
- It will be easier to document, because the API will be single method, not a type+stuff
- It's not horrifying
It's good that the conversion to the types is an explicit one, as this limits the scope for things going wrong with the intended usage.
- It would be nice if the
Text
members were explicitlyprivate
, so there was no question as to your intentions. - I personally do not like the expression-bodied syntax for constructors, but that's probably just me.
$endgroup$
2
$begingroup$
Throwing in a regular constructor is totally valid -- this is how you signal that you cannot create a valid instance using given constructor parameters. Violation of CA1065 is throwing in a static constructor only.
$endgroup$
– Bronx
5 hours ago
$begingroup$
@Bronx wow, thanks for calling that out. I spent some time wondering how to phrase that bit because I couldn't think of a good reason other than to make the tooling happen, so I'm glad to remove it ;)
$endgroup$
– VisualMelon
5 hours ago
$begingroup$
@VisualMelon please see the reasoning update above :)
$endgroup$
– Dmitry Nogin
3 hours ago
add a comment
|
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f229477%2fstring-whitespaces%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
Not sure that adding a 7-line validator class per validation rule (plus typecasting abuse) is any shorter/better than a set of more straightforward composable validating one-liners, something like:
public static class ValidatingTransformers
public static T ThrowsIfNull<T>(this T s, string msg = "") =>
s != null ? s : throw new ArgumentException(msg);
public static string ThrowsIfEmpty(this string s, string msg = "") =>
!string.IsNullOrWhiteSpace(s) ? s : throw new ArgumentException(msg);
public static string EmptyIfNull(this string s) => s ?? "";
public static string NullIfEmpty(this string s) => !string.IsNullOrWhiteSpace(s) ? s : null;
... et cetera
Some other thoughts:
- Replacing empty/whitespace strings with
null
does not look like a great idea to me. Because, well, thenull
and theNullReferenceException
. An empty string looks like a safer alternative. - I'd avoid property setters and mutating a state, even if setters protect invariants. Much simpler, shorter, and safer alternative:
public class Name
public string First get;
public string Middle get;
public string Last get;
public Name(string first, string middle, string last)
First = first.NullIfEmpty();
Middle = middle.ThrowsIfNull("middle name must not be null");
Last = last.ThrowsIfEmpty("last name must not be empty");
Shorter code, one single place for all validations, never ever get an object in an inconsistent state, no issues with concurrent mutations.
New contributor
$endgroup$
$begingroup$
+1, yes - I used extension methods before. The problem is - invoking a method on the null reference makes my feeling scream a way more than a type cast. Would it still be a typecasting abuse for you if relevant model names be used, like(Text)str
or(TextOrNull)str
for the same purposes?
$endgroup$
– Dmitry Nogin
19 mins ago
$begingroup$
Type cast exception will look reasonable then for(Text)
as no white spaces are allowed for the type.
$endgroup$
– Dmitry Nogin
15 mins ago
add a comment
|
$begingroup$
Not sure that adding a 7-line validator class per validation rule (plus typecasting abuse) is any shorter/better than a set of more straightforward composable validating one-liners, something like:
public static class ValidatingTransformers
public static T ThrowsIfNull<T>(this T s, string msg = "") =>
s != null ? s : throw new ArgumentException(msg);
public static string ThrowsIfEmpty(this string s, string msg = "") =>
!string.IsNullOrWhiteSpace(s) ? s : throw new ArgumentException(msg);
public static string EmptyIfNull(this string s) => s ?? "";
public static string NullIfEmpty(this string s) => !string.IsNullOrWhiteSpace(s) ? s : null;
... et cetera
Some other thoughts:
- Replacing empty/whitespace strings with
null
does not look like a great idea to me. Because, well, thenull
and theNullReferenceException
. An empty string looks like a safer alternative. - I'd avoid property setters and mutating a state, even if setters protect invariants. Much simpler, shorter, and safer alternative:
public class Name
public string First get;
public string Middle get;
public string Last get;
public Name(string first, string middle, string last)
First = first.NullIfEmpty();
Middle = middle.ThrowsIfNull("middle name must not be null");
Last = last.ThrowsIfEmpty("last name must not be empty");
Shorter code, one single place for all validations, never ever get an object in an inconsistent state, no issues with concurrent mutations.
New contributor
$endgroup$
$begingroup$
+1, yes - I used extension methods before. The problem is - invoking a method on the null reference makes my feeling scream a way more than a type cast. Would it still be a typecasting abuse for you if relevant model names be used, like(Text)str
or(TextOrNull)str
for the same purposes?
$endgroup$
– Dmitry Nogin
19 mins ago
$begingroup$
Type cast exception will look reasonable then for(Text)
as no white spaces are allowed for the type.
$endgroup$
– Dmitry Nogin
15 mins ago
add a comment
|
$begingroup$
Not sure that adding a 7-line validator class per validation rule (plus typecasting abuse) is any shorter/better than a set of more straightforward composable validating one-liners, something like:
public static class ValidatingTransformers
public static T ThrowsIfNull<T>(this T s, string msg = "") =>
s != null ? s : throw new ArgumentException(msg);
public static string ThrowsIfEmpty(this string s, string msg = "") =>
!string.IsNullOrWhiteSpace(s) ? s : throw new ArgumentException(msg);
public static string EmptyIfNull(this string s) => s ?? "";
public static string NullIfEmpty(this string s) => !string.IsNullOrWhiteSpace(s) ? s : null;
... et cetera
Some other thoughts:
- Replacing empty/whitespace strings with
null
does not look like a great idea to me. Because, well, thenull
and theNullReferenceException
. An empty string looks like a safer alternative. - I'd avoid property setters and mutating a state, even if setters protect invariants. Much simpler, shorter, and safer alternative:
public class Name
public string First get;
public string Middle get;
public string Last get;
public Name(string first, string middle, string last)
First = first.NullIfEmpty();
Middle = middle.ThrowsIfNull("middle name must not be null");
Last = last.ThrowsIfEmpty("last name must not be empty");
Shorter code, one single place for all validations, never ever get an object in an inconsistent state, no issues with concurrent mutations.
New contributor
$endgroup$
Not sure that adding a 7-line validator class per validation rule (plus typecasting abuse) is any shorter/better than a set of more straightforward composable validating one-liners, something like:
public static class ValidatingTransformers
public static T ThrowsIfNull<T>(this T s, string msg = "") =>
s != null ? s : throw new ArgumentException(msg);
public static string ThrowsIfEmpty(this string s, string msg = "") =>
!string.IsNullOrWhiteSpace(s) ? s : throw new ArgumentException(msg);
public static string EmptyIfNull(this string s) => s ?? "";
public static string NullIfEmpty(this string s) => !string.IsNullOrWhiteSpace(s) ? s : null;
... et cetera
Some other thoughts:
- Replacing empty/whitespace strings with
null
does not look like a great idea to me. Because, well, thenull
and theNullReferenceException
. An empty string looks like a safer alternative. - I'd avoid property setters and mutating a state, even if setters protect invariants. Much simpler, shorter, and safer alternative:
public class Name
public string First get;
public string Middle get;
public string Last get;
public Name(string first, string middle, string last)
First = first.NullIfEmpty();
Middle = middle.ThrowsIfNull("middle name must not be null");
Last = last.ThrowsIfEmpty("last name must not be empty");
Shorter code, one single place for all validations, never ever get an object in an inconsistent state, no issues with concurrent mutations.
New contributor
edited 10 mins ago
Confettimaker
5305 silver badges17 bronze badges
5305 silver badges17 bronze badges
New contributor
answered 27 mins ago
BronxBronx
1212 bronze badges
1212 bronze badges
New contributor
New contributor
$begingroup$
+1, yes - I used extension methods before. The problem is - invoking a method on the null reference makes my feeling scream a way more than a type cast. Would it still be a typecasting abuse for you if relevant model names be used, like(Text)str
or(TextOrNull)str
for the same purposes?
$endgroup$
– Dmitry Nogin
19 mins ago
$begingroup$
Type cast exception will look reasonable then for(Text)
as no white spaces are allowed for the type.
$endgroup$
– Dmitry Nogin
15 mins ago
add a comment
|
$begingroup$
+1, yes - I used extension methods before. The problem is - invoking a method on the null reference makes my feeling scream a way more than a type cast. Would it still be a typecasting abuse for you if relevant model names be used, like(Text)str
or(TextOrNull)str
for the same purposes?
$endgroup$
– Dmitry Nogin
19 mins ago
$begingroup$
Type cast exception will look reasonable then for(Text)
as no white spaces are allowed for the type.
$endgroup$
– Dmitry Nogin
15 mins ago
$begingroup$
+1, yes - I used extension methods before. The problem is - invoking a method on the null reference makes my feeling scream a way more than a type cast. Would it still be a typecasting abuse for you if relevant model names be used, like
(Text)str
or (TextOrNull)str
for the same purposes?$endgroup$
– Dmitry Nogin
19 mins ago
$begingroup$
+1, yes - I used extension methods before. The problem is - invoking a method on the null reference makes my feeling scream a way more than a type cast. Would it still be a typecasting abuse for you if relevant model names be used, like
(Text)str
or (TextOrNull)str
for the same purposes?$endgroup$
– Dmitry Nogin
19 mins ago
$begingroup$
Type cast exception will look reasonable then for
(Text)
as no white spaces are allowed for the type.$endgroup$
– Dmitry Nogin
15 mins ago
$begingroup$
Type cast exception will look reasonable then for
(Text)
as no white spaces are allowed for the type.$endgroup$
– Dmitry Nogin
15 mins ago
add a comment
|
$begingroup$
Edit: the tone of this might seem a bit negative, so I'll add that this was a fun one to review in hopes of lightening the mood ;)
Miscellaneous thoughts:
This is horrifying! Why did you do this?!
You can just about get away with this for properties, but for method calls with required/optional fields, a
FormatException
will be inadequate (anArgumentException
telling the caller which argument went wrong is important), which rather limits the scope of this technique.Because the thing is type specific, you could give it a sensible name (e.g.
OptionalString
), make both conversions implicit, and use it as the field type. This would required even less syntax, and would be somewhat less opaque to the maintainer who has to live with this.These need documentation: it's not obvious that an
Optional
should convert""
tonull
: this is enough to put me off it completely.You can get this 'low-char-count syntax by using a
static using
and providing these as static methods to a static class. The advantages would include:- It's not horrifying
- It requires less code, because you don't have to build a whole type and its conversions for each sort of string
- You can't misuse the types in ways you didn't intend, and they don't appear everywhere
- You can throw the static methods at a delegate if you have need
- It's not horrifying
- People who don't hate themselves can use the fully qualified name
- It won't incur an allocation every time you assign a value (though using
struct
s would address this already) - You have greater freedom with the type of checks you can perform (e.g. multiple parameters)
- It will be easier to document, because the API will be single method, not a type+stuff
- It's not horrifying
It's good that the conversion to the types is an explicit one, as this limits the scope for things going wrong with the intended usage.
- It would be nice if the
Text
members were explicitlyprivate
, so there was no question as to your intentions. - I personally do not like the expression-bodied syntax for constructors, but that's probably just me.
$endgroup$
2
$begingroup$
Throwing in a regular constructor is totally valid -- this is how you signal that you cannot create a valid instance using given constructor parameters. Violation of CA1065 is throwing in a static constructor only.
$endgroup$
– Bronx
5 hours ago
$begingroup$
@Bronx wow, thanks for calling that out. I spent some time wondering how to phrase that bit because I couldn't think of a good reason other than to make the tooling happen, so I'm glad to remove it ;)
$endgroup$
– VisualMelon
5 hours ago
$begingroup$
@VisualMelon please see the reasoning update above :)
$endgroup$
– Dmitry Nogin
3 hours ago
add a comment
|
$begingroup$
Edit: the tone of this might seem a bit negative, so I'll add that this was a fun one to review in hopes of lightening the mood ;)
Miscellaneous thoughts:
This is horrifying! Why did you do this?!
You can just about get away with this for properties, but for method calls with required/optional fields, a
FormatException
will be inadequate (anArgumentException
telling the caller which argument went wrong is important), which rather limits the scope of this technique.Because the thing is type specific, you could give it a sensible name (e.g.
OptionalString
), make both conversions implicit, and use it as the field type. This would required even less syntax, and would be somewhat less opaque to the maintainer who has to live with this.These need documentation: it's not obvious that an
Optional
should convert""
tonull
: this is enough to put me off it completely.You can get this 'low-char-count syntax by using a
static using
and providing these as static methods to a static class. The advantages would include:- It's not horrifying
- It requires less code, because you don't have to build a whole type and its conversions for each sort of string
- You can't misuse the types in ways you didn't intend, and they don't appear everywhere
- You can throw the static methods at a delegate if you have need
- It's not horrifying
- People who don't hate themselves can use the fully qualified name
- It won't incur an allocation every time you assign a value (though using
struct
s would address this already) - You have greater freedom with the type of checks you can perform (e.g. multiple parameters)
- It will be easier to document, because the API will be single method, not a type+stuff
- It's not horrifying
It's good that the conversion to the types is an explicit one, as this limits the scope for things going wrong with the intended usage.
- It would be nice if the
Text
members were explicitlyprivate
, so there was no question as to your intentions. - I personally do not like the expression-bodied syntax for constructors, but that's probably just me.
$endgroup$
2
$begingroup$
Throwing in a regular constructor is totally valid -- this is how you signal that you cannot create a valid instance using given constructor parameters. Violation of CA1065 is throwing in a static constructor only.
$endgroup$
– Bronx
5 hours ago
$begingroup$
@Bronx wow, thanks for calling that out. I spent some time wondering how to phrase that bit because I couldn't think of a good reason other than to make the tooling happen, so I'm glad to remove it ;)
$endgroup$
– VisualMelon
5 hours ago
$begingroup$
@VisualMelon please see the reasoning update above :)
$endgroup$
– Dmitry Nogin
3 hours ago
add a comment
|
$begingroup$
Edit: the tone of this might seem a bit negative, so I'll add that this was a fun one to review in hopes of lightening the mood ;)
Miscellaneous thoughts:
This is horrifying! Why did you do this?!
You can just about get away with this for properties, but for method calls with required/optional fields, a
FormatException
will be inadequate (anArgumentException
telling the caller which argument went wrong is important), which rather limits the scope of this technique.Because the thing is type specific, you could give it a sensible name (e.g.
OptionalString
), make both conversions implicit, and use it as the field type. This would required even less syntax, and would be somewhat less opaque to the maintainer who has to live with this.These need documentation: it's not obvious that an
Optional
should convert""
tonull
: this is enough to put me off it completely.You can get this 'low-char-count syntax by using a
static using
and providing these as static methods to a static class. The advantages would include:- It's not horrifying
- It requires less code, because you don't have to build a whole type and its conversions for each sort of string
- You can't misuse the types in ways you didn't intend, and they don't appear everywhere
- You can throw the static methods at a delegate if you have need
- It's not horrifying
- People who don't hate themselves can use the fully qualified name
- It won't incur an allocation every time you assign a value (though using
struct
s would address this already) - You have greater freedom with the type of checks you can perform (e.g. multiple parameters)
- It will be easier to document, because the API will be single method, not a type+stuff
- It's not horrifying
It's good that the conversion to the types is an explicit one, as this limits the scope for things going wrong with the intended usage.
- It would be nice if the
Text
members were explicitlyprivate
, so there was no question as to your intentions. - I personally do not like the expression-bodied syntax for constructors, but that's probably just me.
$endgroup$
Edit: the tone of this might seem a bit negative, so I'll add that this was a fun one to review in hopes of lightening the mood ;)
Miscellaneous thoughts:
This is horrifying! Why did you do this?!
You can just about get away with this for properties, but for method calls with required/optional fields, a
FormatException
will be inadequate (anArgumentException
telling the caller which argument went wrong is important), which rather limits the scope of this technique.Because the thing is type specific, you could give it a sensible name (e.g.
OptionalString
), make both conversions implicit, and use it as the field type. This would required even less syntax, and would be somewhat less opaque to the maintainer who has to live with this.These need documentation: it's not obvious that an
Optional
should convert""
tonull
: this is enough to put me off it completely.You can get this 'low-char-count syntax by using a
static using
and providing these as static methods to a static class. The advantages would include:- It's not horrifying
- It requires less code, because you don't have to build a whole type and its conversions for each sort of string
- You can't misuse the types in ways you didn't intend, and they don't appear everywhere
- You can throw the static methods at a delegate if you have need
- It's not horrifying
- People who don't hate themselves can use the fully qualified name
- It won't incur an allocation every time you assign a value (though using
struct
s would address this already) - You have greater freedom with the type of checks you can perform (e.g. multiple parameters)
- It will be easier to document, because the API will be single method, not a type+stuff
- It's not horrifying
It's good that the conversion to the types is an explicit one, as this limits the scope for things going wrong with the intended usage.
- It would be nice if the
Text
members were explicitlyprivate
, so there was no question as to your intentions. - I personally do not like the expression-bodied syntax for constructors, but that's probably just me.
edited 5 hours ago
answered 6 hours ago
VisualMelonVisualMelon
6,47215 silver badges44 bronze badges
6,47215 silver badges44 bronze badges
2
$begingroup$
Throwing in a regular constructor is totally valid -- this is how you signal that you cannot create a valid instance using given constructor parameters. Violation of CA1065 is throwing in a static constructor only.
$endgroup$
– Bronx
5 hours ago
$begingroup$
@Bronx wow, thanks for calling that out. I spent some time wondering how to phrase that bit because I couldn't think of a good reason other than to make the tooling happen, so I'm glad to remove it ;)
$endgroup$
– VisualMelon
5 hours ago
$begingroup$
@VisualMelon please see the reasoning update above :)
$endgroup$
– Dmitry Nogin
3 hours ago
add a comment
|
2
$begingroup$
Throwing in a regular constructor is totally valid -- this is how you signal that you cannot create a valid instance using given constructor parameters. Violation of CA1065 is throwing in a static constructor only.
$endgroup$
– Bronx
5 hours ago
$begingroup$
@Bronx wow, thanks for calling that out. I spent some time wondering how to phrase that bit because I couldn't think of a good reason other than to make the tooling happen, so I'm glad to remove it ;)
$endgroup$
– VisualMelon
5 hours ago
$begingroup$
@VisualMelon please see the reasoning update above :)
$endgroup$
– Dmitry Nogin
3 hours ago
2
2
$begingroup$
Throwing in a regular constructor is totally valid -- this is how you signal that you cannot create a valid instance using given constructor parameters. Violation of CA1065 is throwing in a static constructor only.
$endgroup$
– Bronx
5 hours ago
$begingroup$
Throwing in a regular constructor is totally valid -- this is how you signal that you cannot create a valid instance using given constructor parameters. Violation of CA1065 is throwing in a static constructor only.
$endgroup$
– Bronx
5 hours ago
$begingroup$
@Bronx wow, thanks for calling that out. I spent some time wondering how to phrase that bit because I couldn't think of a good reason other than to make the tooling happen, so I'm glad to remove it ;)
$endgroup$
– VisualMelon
5 hours ago
$begingroup$
@Bronx wow, thanks for calling that out. I spent some time wondering how to phrase that bit because I couldn't think of a good reason other than to make the tooling happen, so I'm glad to remove it ;)
$endgroup$
– VisualMelon
5 hours ago
$begingroup$
@VisualMelon please see the reasoning update above :)
$endgroup$
– Dmitry Nogin
3 hours ago
$begingroup$
@VisualMelon please see the reasoning update above :)
$endgroup$
– Dmitry Nogin
3 hours ago
add a comment
|
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f229477%2fstring-whitespaces%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown