Lets say I have a populated array of objects.
Resource[] list = new Resource[100000];
And once in a while, I would like to change an object in this list to a default value.
Resource defaultResource = new Resource();
And later on, I would like to check if the item is default or not.
So, I am wondering what the performance differences might be in setting the list object to a default value, versus setting a value to null.
list[i] = defaultResource; /*versus*/ list[i] = null;
So really, I would like to know what goes on behind the scenes when a value is set to null versus setting it equal to something else.
Sorry if this is a dumb question!
There's not much difference between setting a variable to an existing object vs. setting it to null. In both cases, the object that has been referenced by that variable before would get one step closer to becoming eligible for garbage collection, regardless of the new value stored in that variable being a null or a different object. The rest of the assignment goes in the same way, too: CLR does not maintain reference count, so nothing special needs to happen specifically at the point when the assignment is made.
It may be beneficial to store a default object in place of a null to avoid extensive null checking at runtime, though: doing so simplifies the code, and reduces the need for branching at runtime.
One possible option to consider for your scenario - you want the simplification of not having to write null checking code.
Consider subclassing your Resource class with a stub that represents a default value.
public class NoResource : Resource { }
// ... later
if (res is NoResource) {
// handle default value
}
This way, your code is still able to work with Resource objects as it expects to be able to, and you can optionally check for a default Resource easily.
Related
Can I freely add additional operations in C# public property's getter and setter? To what extent? For example, would the following piece of code be okay (returning and editing a collection which is nested into another collection)?
public ObservableCollection<MyEntity> MyCollection
{
get
{
return myColl.Where(p => p.Name == myName).FirstOrDefault().AnotherCollection;
}
private set
{
myColl.Where(p => p.Name == myName).FirstOrDefault().AnotherCollection = value;
}
}
The only bound is the semantics. You may use whatever operations you find suitable, as long as the general property semantics is preserved. Among others, I would check that
access is reasonably fast
if setter finished w/o error, getter should return the value semantically compatible with the set value
if possible, avoid raising exceptions inside
consecutive gets return semantically equivalent values if internal state didn't change
If you keep the semantics, IMHO any operation is allowed.
Realistically, you are allowed to add most anything you want within a propeties getter and setter. Effectively they are not much more than a easy way to avoid writting this:
private String _value;
public String GetValue
{
return _value;
}
public void SetValue(string value)
{
_value = value;
}
So if you can do it in a method, you can do it in a property (doesn't necessarily mean that you should)
As for what is proper, a lot of that depends on context and many people have differing opinions. The general guidelines I try to follow myself are:
Do not do anything that takes too much time. Properties are expected to be fast.
Do not put anything that will throw an Exception unless it is documented and it makes sense. I will use ArgumentException or NullReferenceException in cases where I have to account for values in the property that will break the code, but otherwise if it needs an exception or I call a method that could result in an exception unrelated to the property itself, then method is better.
Use common sense. If you can say to yourself, I want to get or set a value, then a property makes sense. If I want to do something, then you are probably better off with a method.
This goes back to #1, but if there is no backing field to get or set (automatic properties do this in the background anyways), then you have to think about if a property is really the correct approach.
But as I said, these are my guidelines and I do break them from time to time, but when I do, I tend to make sure it is documented that the property is going to do something unexcepted, or long running.
Your example could throw exceptions if myColl or p are null, so unless you will be 100% certain neither could ever possibly be null, then I would not make this a property.
The code you have provided has a "bad code" smell.
You have used FirstOrDefault functions; which may have null values.
myName variable seems to be a class level variable. Then in a property you seem to be using more than one class level variable (myColl and myName); which seems a bit strange for me.
3.You seem to be returning a deep object, AnotherCollection which is a property of the first item in a list. This may lead to problems; what if;
a. myColl is null,
b. myValue is null,
c. FirstOrDefault returns null,
d. AnotherCollection is null.
I think there are two rules:
Common sense - if you think it shouldn't be like that. Then it probably shouldn't be like that.
Principle of least surprise
it's ok in my opinion,
some will say it's ugly, some will say it's valid or just ok, maybe
nice ...
get/set are in depth 2 methods like get() and set()
what are the 'general' coding guidlines ?
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between Property and Field in C#
I know it is a very basic question but I cannot read any valid answer after searching
E.g
public string abc;
public string abc { get; set; }
Please describe this.
(About my terminology: "field" = public variable, "property" = get/set)
One thing to be mentioned additionally to the differences in usage: A property, unlike a field, gets compiled to a method (I think it's called something like get_abc internally). Declaring an auto property from beginning on has therefor two advantages:
1) No problems with reflection. If some reflection code is based on the value being a field, and later you think "well, now I'd like to add null testing" and change to a property, then the reflection code will eventally fail (unless you expected that in the reflection, but that would be extra effort for nothing imho)
2) "Warning" of possible side effects. Fields can only change their values, methods can do arbitrary things to a class. So, declaring a property from beginning on signalizes the possibility of other changes happening in the background. (Of course one shouldn't do weird stuff in a setter, but sometimes it isn't impractical to get additional initialization from one value provided; e.g. measuring the length of a list)
I also would say that it's good style to use properties wherever possible. Especially for the two reasons provided, but also for consistency.
Variables store direct value but property are a window to your class and its variables.
Even though they work the same(almost), one very good thing with field is that if you want to do some extra work with field (like validation or doing any calculations) you can do so.
This will explain you
public string _abc;
public string abc
{
get
{
return _abc;
};
set
{
if (value == null)
_abc = "";
else
_abc = value;
};
}
Here if null is passed to property abc then it will be checked it and an empty value will be assigned to _abc. otherwise value.
If we wanted this with a variable. every where we had to do this.
if(foo == null) // here foo is some string
_abc = ""
else
_abc = foo;
with property this can be done like
abc = foo;
Now it will check for in the set section of property.
Properties can contain some code on setting/getting the value. Public variables can't and will not contain any code when you access them. This is a huge difference.
Using a property you're saying to whomever uses you're code that there might be some code behind the value now or in the future.
Using a public variable you're saying its just a boring old field that will contain some value.
One reason for using an auto property instead of a Field is compatibility.
For example, when you assign a field, the CLR does just that. It sets the field.
When you have a property (auto or not), and you type
someObject.Whatever = "Value";
it looks like you are assigning a field, but in reality, the C# compiler inserts something like this for you:
someObject.set_Whatever("Value");
That's not the same as setting a field. And if you have a field and change it to a property later (e.g. if you want to implement change notifications or things like that), you will have to recompile all assemblies that used the original field, since assigning a Field requires different code than setting a property (no matter if auto or not).
There is almost never a reason to use a public field. Automatic properties can be inlined at runtime, so there would be no performance difference. And they leave the possibility open to add additional logic to your get / set methods without having to recompile dependent assemblies.
Same difference as a property over public variable such as property support binding but variable not.
Is the condition check really redundant in the following sample?:
public class MyClass {
public bool MyProperty { get; set; }
public void DoSomething(bool newValue) {
// R# says: redundant condition check before assignment
// on the following line:
if (MyProperty != newValue) { // <======
MyProperty = newValue;
}
}
}
I know that either way MyProperty will be set to newValue, but is the check redundant?
In Adobe Flex, the getter is called implicitly by the VM its running on whenever a setter is called even though no explicit check is being made. The end result is that checking before an assignment results in two checks, one explicit and one implicit, resulting in a redundant check. Does anything similar happen in C#?
There are only two situations where I've seen this type of check.
The first is when there is an additional line of code which sets another property on the object to True to indicate that the object has been modified. This is typically used when trying to decide whether to persist the state of the object to something like a database.
The second situation is when the types in question are immutable. You might want to avoid setting the value and therefore creating a new string, for example, when the values are the same. Even then, I've only seen it in certain apps where memory usage is critical.
In this specific case, it's logically redundant, since there is no code being executed in the getter - just a straight wrapper around a private field. If you're in the habit of putting stuff in your getter that would have side effects, I'd say to disable that R# warning.
Might be worth trying to put something in the getter of the property, and see if ReSharper still thinks it's redundant. If it does, then I'd call that a R# bug.
I would say that the check is redundant. It would make more sense if you had an implementation of INotifyPropertyChanged, but then the check would be in the setter to avoid triggering the event if no actual change is done.
if (MyProperty != newValue) IS redundant, leaving the line will yield the same result
My question is: can I check whether a variable (string or int/double type) or an array (string or int/double type) is initialized in C#?
Thanks in advance.
You are guaranteed some sort of initialization. For any static or instance members, all variables are automatically initialized when the type or instance is constructed, either explicitly or implicitly (in which case default(Type) is the value, so 0 for numeric types, null for strings and other reference types, etc.).
For local variables, they cannot be used before declaration, so if you can check it, it's been initialized.
Yes you can.
For types that require instances (string or arrays, as you asked), you can verify if they are null.
You could do this many ways but one way is :
if (myObject == null)
{
//initialize it here
}
Primitive data types do not require instancing. For example:
int i;
wont be equal to null, it will be equal to 0.
Try This, :
If var = NULL Then
MsgBox ('Not initialized')
End If
C# requires that all variables be initialized to some value before you read them.
The code block:
int i;
if(i == 0)
{
// something...
}
Will generate a compile-time error because you're trying to access the value of i before assigning it. This also applies to objects (although you can initialize them to null to begin with).
If you are wanting to know if you have modified from your initial assignment, then no, there is no way of telling that directly unless the initial assignment is to a sentinel value that will not be repeated by a subsequent assignment. If this is not the case you will need an extra bool to track.
No. However, you will have a compiler error if it is a local variable. If it is a class member then it is automatically initialized to the default (0 for ints, null for objects, etc.)
tongue in cheek, but accurate answer
Scan your source code and find all usages and declarations of the variable to verify that it is initialized either at declaration, or else somewhere guaranteed before using it.
If I write:
SomeType simpleName = classWithLongName.otherLongName;
And then use "simpleName" instead of "classWithLongName.otherLongName", will this change the program in any way (for instance performance wise)?
What does the compiler do with this? Does it copy+paste "classWithLongName.otherLongName", everywhere I use "simpleName".
No, the C# compiler doesn't translate a call to "simpleName" to be the same as copying and pasting "classWithLongName.otherLongName". The difference could be profound or simply semantic, but what you're doing is assigning the value from classWithLongName.otherLongName to simpleName. Whether the type is a value type or a reference type will determine exactly what happens and what will happen if you manipulate that value, but you're not creating a function pointer or delegate in doing that.
Whether it will have an effect on performance really isn't something that can be answered here, other than to say that it won't have a NEGATIVE effect. We can't say if it will have a positive effect, since that would depend on what actually happens when you call classWithLongName.otherLongName. If that's an expensive operation, then this could make it faster, but the downside would be that any differences in value upon subsequent calls to classWithLongName.otherLongName wouldn't be reflected if you cached its value in simpleName.
It depends what "otherLongName" is actually doing. If it's a property, then the difference is between executing the property several times or only executing it once. That may or may not change the behaviour of the program in a significant way, depending on what it's doing.
The compiler is only allowed to cache the value and re-use it itself when you always type "classWithLongName.otherLongName" if it knows that the value will not change in the course. However, this is seldom the case.
Therefore, if "classWithLongName.otherLongName" does perform some computation, you'll usually get better performance by caching it manually in a local variable as you suggested. However, keep in mind that you are working with a cached value and that changes in the original value or property will not be reflected on your cached value.
The length of the name however is just metadata and has no influence whatsoever on runtime performance, since the name is already resolved to an internal handle during compilation.
Is this a question about instances or classes?
For instance
namespace MyCompany.MyApp.LongNamespaceName
{
public class MyClassWithALongName {
public SomeType AnInstanceProperty {get;set;}
public static SomeType AStaticProperty {get { ... }}
}
}
Now:
//this gets the static property
SomeType simpleName = MyClassWithALongName.AStaticProperty;
Alternatively:
MyClassWithALongName anInstanceWithALongName = new MyClassWithALongName();
//this gets the instance property
SomeType simpleName = anInstanceWithALongName.AnInstanceProperty;
These will behave in different ways.
There's another case here though, you can create an alias for the actual name of the class:
using simpleName = MyCompany.MyApp.LongNamespaceName.MyClassWithALongName;
...
simpleName anInstance = new simpleName ();
If classWithLongName.otherLongName is a property, than changes to simpleName will NOT change classWithLongName.otherLongName.
If classWithLongName.otherLongName is a public data member (a field) of a value type, than changes to simpleName will NOT change classWithLongName.otherLongName.
If classWithLongName.otherLongName is a public data member (a field) of a reference type, than changes to simpleName WILL change classWithLongName.otherLongName.
Assuming your type is an object (reference) type then simpleName will end up containing a reference to the object returned by classWithLongName.otherLongName. If you are then going to make lots of calls to properties on that object then you may get a performance improvement, especially if otherLongName is a property as opposed to a field.
You can always make it a function.
SomeType simpleName() { return classWithLongName.otherLongName; }