struct with string member? Invalid default instance acceptable? - c#

Is this a good candidate for a struct?
Consider this immutable struct example where the constructor validates input and stores the validated data as a single "routing code":
struct RoutingCode
{
private readonly string routingCode;
RoutingCode(string prefix, string service, string sender)
{
// Validate prefix, service, sender strings
// ...
if (isInvalid) throw ArgumentException();
//
this.routingCode = prefix + service + sender;
}
// Gets the validated routing code.
public string Routing
{
return this.routingCode;
}
public int RoutingLength
{
return this.routingCode.Length;
}
}
This simplified example appears to me to be a good candidate for using a struct instead of a class:
It is immutable.
It represents a singular value.
The instance size is small.
The problem is that all structs have an implicit default constructor. In this example, the default constructor RoutingCode() would instantiate an object where the Routing property returns null—which is an invalid routing code. This is a different from other structs such as Point or BigInteger where the backing fields contain a very logical and valid "zero" for default instances.
In addition to not ensuring a valid routing code, the RoutingLength property throws a NullReferenceException if called on a default instance.
What are the arguments for keeping this a struct versus making it a class?

You can easily solve your default value problems:
struct RoutingCode
{
private readonly string routingCode;
RoutingCode(string prefix, string service, string sender)
{
// Validate prefix, service, sender strings
// ...
if (isInvalid) throw ArgumentException();
this.routingCode = prefix + service + sender;
}
public string IsValid
{
get { return this.routingCode != null; }
}
// Gets the validated routing code.
public string Routing
{
get { return this.routingCode; }
}
public int RoutingLength
{
get { return this.routingCode == null ? 0 : this.routingCode.Length; }
}
}
OK, now none of the properties throw exceptions and you have a way to tell if the value is invalid. The question at hand is whether or not this is a good candidate for a struct. You are right that it is (1) immutable, (2) small, and (3) logically a value. If you're willing to live with the fact that you can represent an invalid value, then this is probably a good candidate for a struct.
A better question though is: is there a good reason for this not to be a class? Rather than looking for objections to making it a struct, look for objections to making it a class.

It's possible for a hidden-field struct to have uninitialized instances behave as though they holds any particular desired value [the default value must be the same for all uninitialized instances of a given type]. Simply have each property accessor or method check whether the type holds the system default value and, if so, substitute the desired default value instead.
If one wanted to allow code to create an instance where Routing was null and not have such an instance assume that Routing was the default value, one could have the type declare a static string equal to a new GUID (or something else which isn't going to appear elsewhere), and then modify the constructor and get methods:
static string stringRepresentingNull = Guid.NewGuid().ToString();
RoutingCode(string wholeString)
{
if (wholeString == null)
wholeString = stringRepresentingNull;
this.routingCode = wholeString;
}
public string Routing
{
get {
if (this.routingCode == null)
return "12-3456-789"; // Default routing string
else if (Object.ReferenceEquals(routingCode,stringRepresentingNull)
return null;
else
return routingCode;
}
Note that even if outside code somehow manages to guess the GUID that is associated with the type, there's no way for outside code to generate a string where ReferenceEquals will match stringRepresentingNull.
On a similar vein, if one wanted to have an int property with a default value of 123, one could store backingField=(desiredValue ^ 123) and have the property getter yield backingField ^ 123.
The question of whether the type should be a struct or a class largely boils down to one of whether one wants to have the default value of the type behave as a null, or as a valid value. If one wants a null default, use a class. If one wants a valid default, use a struct.

Related

C# define that a class instance can never be null (it only contains no data)

Out of curiosity: Is there a way to create a class whose reference to the class instance can never be set to null?
Like haveing only a readonly pointer that can only be set to null by the class itself.
What I have in mind:
I would want to have an easy to read /use object that either exists with data or exists without (shown by an attribute like hasData = false). It is always accessable and should never be null / point to nowhere which as a side effect gets also rid of NullReferenceExceptions for objects that are sometimes supposed to not have a value without the need of checking for null.
This feature does not exists (yet). There is big discussion of non-nullable reference types at Roslyn forum: non-nullable reference types (the one billion $ mistake). But currently you cannot restrict reference type variable from assigning null value.
You can use value type (struct) instead, but it's not stored in heap, passed by value etc.
All other options will not guarantee that someone will not assign null to variable of your reference type. But you still can use something like Null Object pattern to simplify your life (processing objects without data in same way as usual objects).
In such a case, you may want to use a struct instead of a class. Class is a reference type and therefore its default value is null, hence a variable containing an instance can be nulled (assigned null). There is no way to prevent it. On the other hand, struct is a value type and default for struct is an empty struct - i.e. a struct whose members are set to their defaults (0 for an int field, null for a field of a reference type etc.)
Example of a struct
public struct Foo
{
public int Bar;
}
And its usage (notice it is not instantiated but still it is NOT null)
Foo foo;
foo.Bar = 1;
More about structs can be found here on the MSDN sites.
As Anton mentioned, you could use a struct which cannot have a default value of null. But I am thinking you want something more like this:
public class DataObject
{
public static bool HasData
{
get
{
return myObject != null;
}
}
public static DataObject PresistentDataObject
{
get
{
return myObject;
}
}
static DataObject myObject = new DataObject();
}
This code seems like bad practice. And maybe you'd want to resort to something like dependency injection with a singleton which will avoid setting up a state class like this.
Typically, the motivation behind such a question drives the qualities/properties of a solution.
Here, I suppose, the motivation is to avoid runtime exceptions of (faulty) code which tries to access a null reference as if it held an instance.
class Foo<T> {
T data; // might be null or hold an instance...
Foo<T>() {
data = GetInstanceOfTInMysteriousWays(); // might return null...
}
bool DoSomething() {
return data.Value > 5; // might throw an exception...
}
// ... more members...
}
To prevent this type of errors, you could borrow from C#'s cousin language F#.
If the function T GetInstanceOfTInMysteriousWays<T>() by design and contract is permitted to either return an instance or a null value, a better design of that function would be to have it return not T but an Option<T>. Then, the type of Foo.data would not be T but Option<T> and the user code in DoSomething() could not simply access member data.Value. Thus, this common pattern of bugs would be eliminated.
// Improved code from above
class Foo<T> {
Option<T> data; // Option is a struct type and cannot be null...
Foo<T>() {
data = GetInstanceOfTInMysteriousWays();
}
bool DoSomething() {
if (data.IsSome() ) {
return data.TryGetValue().Value > 5;
}
return false;
}
}
Now the only question is, where to find that Option type in C#? There are several github projects creating such a type (google is your friend). You could also consider to link the F# core library and use the Option type defined there, maybe along with a little helper as is shown in this gist snippet.
If your class is named foo, then you would have at least one constructor (possibly more). In that constructor you would assign the variable to false.
public foo(){
hasData = false;
}
As #Anton points out, this only works if the variable is instansiated.
foo f = new foo();
it would still be null if you assigned it as null:
foo f = null;
I'm not sure, I understand the question correctly or not. Let me add
some points here:
Hope that you misunderstand the term Instance, If you create an instance of the class then it will not be null, Let myClass be a class that you have created already. You are not creating any instance of the class by using myClass myClassObject. The myClassObject will became an instance of the class only when an instance of the class is assigned to it, Until then it is null which means not existing.
As others have mentioned, you'd need a struct for that.
However, we can tackle this from a different angle (in a class):
Since the variable can point to null, let's define the variable in a way that it can't be set to null:
private Class1 _c = new Class1();
public Class1 c { get { return _c; } set { if (value != null) _c = value; } }
so c will not be set to null.
A struct per your requirements:
struct Struct1
{
public bool hasData { get { return Data != null; } }
public Class1 Data;
}

C#: type safety over sets of integers (e. g. enums)

I have a case where I have several sets of numbers (register values). I want to improve readability and also to check appropriate types (only certain values make sense in certain functions).
In my particular implementation, I made them enums - so I have a set of enums now.
Now I seem to have reached the end on this approach, since I want to divide them into sets of valid enums for certain applications - so function A could for example take (a value from) enumA, enumB and enumC as input, but not enumD which is a description of different functionality.
I already looked into enums in interfaces and enum inheritance - both are dead ends, not possible in C#.
I wonder now how the solution to this problem might look like. I would like to get intellisense on the possible values and also have some type safety, so that I could not (well, at least not without maliciously casting it) feed the wrong values in.
How to achieve this?
(Possible solutions would be to simply write several functions taking several different enums - still possible but not really nice, or something like Is there a name for this pattern? (C# compile-time type-safety with "params" args of different types) - both just seems not too nice.)
One option is to scrap enums and use your own clases designed to mimic enums. It will be a bit more work for you to set them up, but once you do it will be easy enough to use, and will be able to have the functionality you've described.
public class Register
{
private int value;
internal Register(int value)
{
this.value = value;
}
public static readonly Register NonSpecialRegister = new Register(0);
public static readonly Register OtherNonSpecialRegister = new Register(1);
public static readonly SpecialRegister SpecialRegister
= SpecialRegister.SpecialRegister;
public static readonly SpecialRegister OtherSpecialRegister
= SpecialRegister.OtherSpecialRegister;
public override int GetHashCode()
{
return value.GetHashCode();
}
public override bool Equals(object obj)
{
Register other = obj as Register;
if (obj == null)
return false;
return other.value == value;
}
}
public class SpecialRegister : Register
{
internal SpecialRegister(int value) : base(value) { }
public static readonly SpecialRegister SpecialRegister = new SpecialRegister(2);
public static readonly SpecialRegister OtherSpecialRegister = new SpecialRegister(3);
}
Given this, you could have a method like:
public static void Foo(Register reg)
{
}
That could take any register, and could be called like:
Foo(Register.NonSpecialRegister);
Foo(Register.OtherSpecialRegister);
Then you could have another method such as:
public static void Bar(SpecialRegister reg)
{
}
Which wouldn't be able to accept a Register.NonSpecialRegister, but could accept a Register.OtherSpecialRegister or SpecialRegister.SpecialRegister.
Sounds like you have exhausted the capabilities of the static type system on the CLR. You can still get runtime validation by wrapping each integer with a class that validates that the value you try to store in it actually is a member of the static set.
If you have a reliable test suite or are willing to do manual testing this will at least catch the bugs instead of the bugs causing silent data corruption.
If you have multiple "sets" that you want to keep apart you can either use class inheritance or have a set of user-defined conversion operators which validate that the conversion is OK at runtime.
I don't know what specific requirements you have but maybe you can use class-based inheritance to check some properties statically. The base class would be the larger set in that case and derived classes would specialize the set of allowed values.
You have basically two options:
Option 1: Multiple enums
Create multiple enums, one for each application, and replicate the values in each enum. Then you can cast between them. For example:
enum App1
{
Data1 = AppAll.Data1,
Data2 = AppAll.Data2,
Data42 = AppAll.Data42,
}
enum App2
{
Data2 = AppAll.Data2,
Data16 = AppAll.Data16,
Data42 = AppAll.Data42,
}
enum AppAll
{
Data1 = 1,
Data2 = 2,
Data16 = 16,
Data42 = 42,
}
App1 value1 = (App1)AppAll.Data2;
App2 value2 = (App2)value1;
This will give you IntelliSense.
Option 2: Determine which are allowed
Create a method that returns a boolean on which values are allowed (this may be virtual and overridden for each application). Then you can throw an exception when the enum value is wrong.
public bool IsAllowed(AppAll value)
{
return value == AppAll.Data2
|| value == AppAll.Data16
|| value == AppAll.Data42;
}
if (!IsAllowed(value))
throw new ArgumentException("Enum value not allowed.");
This will not give you IntelliSense.
A few notes:
You cannot have inheritance for enums because under the covers enums are represented as structs (i.e. value types).
In C# you can literally cast any value to your enum type, even when it is not a member of it. For example, I can do (App1)1337 even when there is no member with value 1337.
If you want compile type checking, you are better off with distinct enums for distinct cases. If you want to have a master enum with all of your possibilities you can write a test that ensures that all of your "child" enum lists are valid subsets of the master (in terms of Int casts).
As an alternative, I would have to wonder (since no code is provided, I can only wonder) if you might not be better served with objects with methods for each enum option. Then you inherit out objects with the various methods instead of enums. (After all, it seems that you are using Enums as proxies for method signatures).

Work with Custom Attributes on my C# POCO class

In my project I have one class called Area like below.
The property "CodArea" I want to put one custom attribute like [NaoSelecionarAttr(true)].
This is working fine but when I create one instance of the class I can not get this custom attribute. Something like this:
Area areaPoco = new Area();
areaPoco.CodArea.GetType().GetCustomAttributes(typeof(NaoSelecionarAttr),true).ToList();
[Serializable]
public class Area
{
#region Private Members
private decimal _numChave;
private string _codArea;
public Area()
{
_numChave = 0;
_codArea = null;
}
public Area(decimal pNumChave, string pCodArea)
{
NumChave = pNumChave;
CodArea = pCodArea;
}
public virtual decimal NumChave
{ get { return _numChave;}
set { _numChave = value;}
}
[NaoSelecionarAttr(true)]
public virtual string CodArea
{
get { return _codArea; }
set { _codArea = value;}
}
}
public class NaoSelecionarAttr : Attribute
{
public bool NaoSelecionar { get; set; }
public NaoSelecionarAttr(bool pSim) { this.NaoSelecionar = pSim; }
}
}
There are some problems with your code.
The first problem in the code is that you are calling the default constructor on Area, which initializes _codArea to null. And then you try to call GetType on it, which fails with a NullReferenceException, as expected.
The second problem is that you want an attribute of a property of a class. So you must inspect (or reflect) the class, not the property. You see, when you write areaPoco.CodArea... the compiler resolves it to the result of your get expression, in this case, the field _codArea. By calling GetType() on _codArea, what you retrieve is a String type, not your Area type. I know this may seem confusing at first, but properties aren't types, so you can't reflect on them.
What you should do, then, is:
Area areaPoco = new Area();
NaoSelecionarAttr attr = (NaoSelecionarAttr) (areaPoco.GetType().GetProperties().Single(p => p.Name == "CodArea").GetCustomAttributes(typeof(NaoSelecionarAttr), true).Single());
bool naoSelecionar = attr.NaoSelecionar;
If I may, I want to give you some tips as well:
Your notation for the non-default constructor seems reminiscent of C/C++. There usually isn't a good reason to stick a "p" prefix in the parameters.
Instead of NaoSelecionar, which is a negative property, I recommend you work with "Selecionar". The deal is that you can easily confuse a negative sentence with its correspondent positive one. A month from now you will ask, "ok, the parameter is false, so should I select or not this property?". False usually means NOT, so, your default interpretation would be not to select something when the property is false.
Your default constructor is initializing a property to null. Just as I described above, this can result in bugs. Either initialize it to a default value (string.Empty), or remove the default constructor and use only the one that requires the user to provide a value to string. And validate those parameters as well -- the user might provide again a null to the string. (An object should be valid when first constructed)
One final tip. Your NaoSelecionar attribute gets a boolean parameter. The last bullet was exactly about that -- you can confuse whether having a true property for your attribute means "não" or "sim". Well, why don't you simply remove the parameter and then work with a negative parameter? There's no need to pass true or false to NaoSelecionar, since all you need to do is iterate through your class and find which properties have this attribute applied to them.
Why do you use areaPoco.CodArea.GetType()? I think you should use areaPoco.GetType(). Because your custom attribute belongs to the Area class, not to the string.

How to have a C# readonly feature but not limited to constructor?

The C# "readonly" keyword is a modifier that when a field declaration includes it, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.
Now suppose I do want this "assign value once" constraint, but I would rather allow the assignment be done outside of constructors, a lazy/late evaluation/initialization maybe.
How could I do that? and is it possible to do it in a nice way, for example, is it possible to write some attribute to describe this?
If I understand your question correctly, it sounds like you just want to set a field's value once (the first time), and not allow it to be set after that. If that is so, then all the previous posts about using Lazy (and related) may be useful. But if you don't want to use those suggestions, perhaps you can do something like this:
public class SetOnce<T>
{
private T mySetOnceField;
private bool isSet;
// used to determine if the value for
// this SetOnce object has already been set.
public bool IsSet
{
get { return isSet; }
}
// return true if this is the initial set,
// return false if this is after the initial set.
// alternatively, you could make it be a void method
// which would throw an exception upon any invocation after the first.
public bool SetValue(T value)
{
// or you can make thread-safe with a lock..
if (IsSet)
{
return false; // or throw exception.
}
else
{
mySetOnceField = value;
return isSet = true;
}
}
public T GetValue()
{
// returns default value of T if not set.
// Or, check if not IsSet, throw exception.
return mySetOnceField;
}
} // end SetOnce
public class MyClass
{
private SetOnce<int> myReadonlyField = new SetOnce<int>();
public void DoSomething(int number)
{
// say this is where u want to FIRST set ur 'field'...
// u could check if it's been set before by it's return value (or catching the exception).
if (myReadOnlyField.SetValue(number))
{
// we just now initialized it for the first time...
// u could use the value: int myNumber = myReadOnlyField.GetValue();
}
else
{
// field has already been set before...
}
} // end DoSomething
} // end MyClass
Now suppose I do want this "assign value once" constraint, but I would rather allow the assignment be done outside of constructors
Note that lazy initialization is complicated, so for all of these answers you should be careful if you have multiple threads trying to access your object.
If you want to do this inside the class
You can use the C# 4.0 built-in lazy initialization features:
http://msdn.microsoft.com/en-us/library/dd997286.aspx
http://msdn.microsoft.com/en-us/library/dd642331.aspx
http://sankarsan.wordpress.com/2009/10/04/laziness-in-c-4-0-lazyt/
Or for older versions of C#, just supply a get method, and check if you're already initialized by using a backing field:
public string SomeValue
{
get
{
// Note: Not thread safe...
if(someValue == null)
{
someValue = InitializeSomeValue(); // Todo: Implement
}
return someValue;
}
}
If you want to do this outside the class
You want Popsicle Immutability:
http://blogs.msdn.com/b/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx
http://msdn.microsoft.com/en-us/library/ms750509.aspx
http://csharpindepth.com/Talks.aspx (search for "popsicle immutability" and you'll find a video)
Basically:
You make the whole class writable, but add a Freeze method.
Once this freeze method is called, if users try to call setters or mutator methods on your class, you throw a ModifyFrozenObjectException.
You probably want a way for external classes to determine if your class IsFrozen.
BTW, I made up these names just now. My selections are admittedly poor, but there is no generically followed convention for this yet.
For now I'd recommend you create an IFreezable interface, and possibly related exceptions, so you don't have to depend on the WPF implementation. Something like:
public interface IFreezable
{
void Freeze();
bool IsFrozen { get; }
}
You can use the Lazy<T> class:
private readonly Lazy<Foo> _foo = new Lazy<Foo>(GetFoo);
public Foo Foo
{
get { return _foo.Value; }
}
private static Foo GetFoo()
{
// somehow create a Foo...
}
GetFoo will only be called the first time you call the Foo property.
This is know as the "once" feature in Eiffel. It is a major oversight in C#. The new Lazy type is a poor substitute since it is not interchangeable with its non-lazy version but instead requires you to access the contained value through its Value property. Consequently, I rarely use it. Noise is one of the biggest problems with C# code. Ideally, one wants something like this...
public once Type PropertyName { get { /* generate and return value */ } }
as oppose to the current best practice...
Type _PropertyName; //where type is a class or nullable structure
public Type PropertyName
{
get
{
if (_PropertyName == null)
_PropertyName = /* generate and return value */
return _PropertyName
}
}

Hash a delegate function in C#

How can I get a hash of a delegate function in C#. I want to be able to tell if different delegates are being sent into my function. My code looks something like this:
public string GetContent(Func<string, bool> isValid)
{
// Do some work
SomeFunctionToHashAFunction(isValid)
}
I would use .GetHashCode() but the .NET framework doesn't guarantee that these will be unique.
EDIT
I have some cached content that I'm validating, but I only want to validate it once. However, if the validation function changes, then I'll need to re-validate the cached content. I'm not sure if the ObjectIdGenerator will work in this instance since I need to identify if two anonymous functions have the same implementation.
By definition, a hash is not guaranteed to be unique, so hashing is not what you want.
Instead, you want to determine whether the instance of the delegate has been "seen" before. To do this, you could use ObjectIdGenerator:
private static readonly ObjectIdGenerator oidg = new ObjectIdGenerator();
public string GetContent(Func<string, bool> isValid)
{
bool firstTime;
oidg.GetId(isValid, out firstTime);
if (!firstTime)
{
...
}
}
However, even with this technique there are some pitfalls to be aware of:
ObjectIdGenerator stores a reference to each object you pass to it
Delegates to the same function are distinct objects, and would therefore return different IDs
Perhaps if you explain what it is you're trying to achieve, there may be a much better way to go about it.
EDIT: Given your updated requirements, I would just define the validation delegate as a property. If the property changes, you know you need to re-validate. GetContent() would therefore not need any parameters:
public Func<string, bool> IsValidHandler
{
get { return this.isValidHandler; }
set
{
this.isValidHandler = value;
this.requiresValidation = true;
}
}
public string GetContent()
{
if (this.requiresValidation && this.isValidHandler != null)
{
// do validation
this.requiresValidation = false;
}
// return content
}
You might even simplify further and do the validation when the IsValidHandler property is set (not in the GetContent method).
There is no (at least non completely hacky) way to hash anonymous function/delegate. Even if function implementation is the same, it might be a closure - so validation outcome might be different based on the context state. Consider this example:
public class Validator
{
public string SomeState { get; set; }
public Validator(string someState)
{
SomeState = someState;
}
public bool IsValid(string input)
{
return input == SomeState;
}
}
// assume your 'input' being validated is "foo"
GetContent((new Validator("foo")).IsValid); // IsValid returns true
GetContent((new Validator("bar")).IsValid); // IsValid returns false
So the only way be sure of whether the validation function is unique would be to have caller define uniqueness of validation implementation and have the caller pass that information to you. You would have to switch to using some kind of validator interface, something along these lines:
//
// Your code
//
public string GetContent(IValidator validator,
IEqualityComparer<IValidator> comparer)
{
// for tracking used validators, use instance
// of 'new HashSet<IValidator>(comparer)'
// this will give you a hashset of unique validators
}
public interface IValidator
{
bool IsValid(string input);
}
//
// Your callers code
//
public class Validator : IValidator
{
// same as Validator class code above
}
public class ValidatorEqualityComparer : IEqualityComparer<Validator>
{
public bool Equals(Validator v1, Validator v2)
{
return GetHashCode(v1) == GetHashCode(v2);
}
public int GetHashCode(Validator v)
{
int hCode = GetMyStringHash(v.GetType().GUID.ToString() + v.SomeState);
// as for GetMyStringHash() implementation for this example,
// you can use some simple string hashing:
// http://www.techlicity.com/blog/dotnet-hash-algorithms.html
return hCode;
}
}
Then you can call your method like this:
GetContent(new Validator("foo"), new ValidatorEqualityComparer());
So the most important part to note here, is that when implementing ValidatorEqualityComparer.GetHashCode() you use validator object state (object value based) hashing. Only this will ensure true uniqueness of validation logic.
Hashes are not intended to be unique. In terms of equality, the only thing you can use them for is to determine whether two objects are not the same. As such, they can be used as a quick first test; if the hashes are different, there is no use to do any further comparisons; the two objects are not the same. If the hashes do match, the objects may be the same, but they may also not be, so you need to perform some deeper analysis in order to determine equality.
Why not just use HashSet to store delegates? Then you can just use .Contains(isValid) to check if the delegate has been given already.
In other words, someone already solved this problem. No reason for you to also solve it.
GetHashCode WILL be unique between different object to a factor of 2^122, that seems pretty safe.
Otherwise, create a class, add a func property, and a bool that is, HasBeenSeen.
Should get the job done.

Categories

Resources