Just started learning C# (in xaml), so appreciate some elaboration:
((MSAvalon.Windows.Serialization.ILoaded)(_Text_2_)).DeferLoad();
Not sure what all the round brackets means... does it mean "_Text_2_" is a child of object "MSAvalon.Windows.Serialization.ILoaded" ?
and if so... why not just something like:
MSAvalon.Windows.Serialization.ILoaded._Text_2.DeferLoad();
_Text_2_ is casted to a MSAvalon.Windows.Serialization.ILoaded Object/Interface and then the method DeferLoad is called
This is a typecast, used to tell the compiler that a variable is of a particular type when it's not obvious. It could have been used like this:
class Foo {
private object _Text_2_;
void Method() {
((MSAvalon.Windows.Serialization.ILoaded)_Text_2_).DeferLoad();
}
}
Leaving out the typecast here would cause a compiler error, since DeferLoad is not a method of object. You're telling the compiler here that you have some special knowledge that _Text_2_ is really what you say it is.
Basically it's started with (( so that DeferLoad can be called. I'll illustrate with an example.
Lets say you do the following.
object s = "Hello world";
s now contains a string. If you want to make this string uppercase using a cast (as in your example, I can't simply write this
(string)s.ToUpper();
ToUpper() can't be called, since it's not valid on a variable of type object. If you rewrite this to
((string)s).ToUpper()
it's valid. Because of the brackets, s is casted to a string first, then string.ToUpper() is called on the variable.
Note that in this case (s as string).ToUpper() would be a cleaner approach.
Related
So on my quiz for my c# course one of the questions was
How would you declare a function that requires the calling code to modify the original contents of an input parameter?
And for some reason the answer is
void mystery(out double clue)
I thought to use the out parameter you must use the same data type as the variable?
So like this
double mystery(out double clue)
So, let consider the following pseudo-code:
R foo(T)
The function receives something of type T as input parameter. Also it returns something as a result of type R. In your quiz, the question was about T. So, the only way to let foo() to modify input parameter T is to add special signature around the T:
R foo1(out T t) {...}
R foo2(ref T t) {...}
Well, actually there are two ways to do that, you see? The difference is: foo1 can accept non-initialized values and then set them to proper value inside foo1() code. However, foo2 requires the parameter to be initialized before calling foo2(). Because null value can not be referenced, thus can not be modified.
And, as kindly emphasized by Hans Kesting in comments below, "out" means "requires the calling code to modify the original contents of an input parameter". So, this is it.
See these link for more details:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/out-parameter-modifier
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/ref
I have a custom class structure as follows.
public interface Stuff { }
public Thing : Stuff
{
public new String ToString() { return "That's the thing!"; }
}
Then, in other parts of my code I have a method that takes a String object as a parameter. The first line compiles, while the second one doesn't. I thought that ToString was called by default when sending in an object. And Stuff, being inherited from Object class should have ToString already implemented (and also, in my case, shadowed by my implementation).
Thing thing = new Thing();
MustHaveString(thing.ToString());
MustHaveString(thing);
What do I miss?
You're probably getting confused because of calls such as String.Format and Console.WriteLine, as well as string concatenation operator, which call ToString implcitly.
This isn't a general rule though. In general, if you need a string, you need to either call ToString explicitly or have some other conversion. I wouldn't recommend creating implicit conversions to string - they're likely to cause more pain than joy.
I'd also recommend against creating a new ToString method. Instead, you should override the one declared by object. Hiding methods is almost always a bad idea; there are a few cases where you really want to do it (e.g. to change the return type) but it should be avoided where possible.
Assuming MustHaveString looks something like:
public void MustHaveString(string arg)
Then simply saying thing results in a compile error, unless thing has an implicit conversion to string. Without the implicit conversion, you must do thing.ToString(). If, however, your code is like:
string myString = "This is a thing: " + thing;
Then the ToString is implicitly called, so it's optional.
In most cases, I would recommend explicitly calling the ToString method, to make it clear to people reading your code what's going on.
Edit: since this answer was accepted, I thought I should also mention that you should make your ToString() method an override, not a new. This will result in the normally-expected behavior, which is what I described above.
I recently wrote the following statement by accident.
MyCollection myCollection = new MyCollection();
SomeMethod(myCollection.SomeVoidOperation());
Stupidly it took me some time to work out why it didn't work (Had a brainfart) but then it got me thinking; why is such a statement actually invalid in any general C type syntax context?
I understand that I can accomplish the same functionality with method chaining but what I don't get is why such a feature isn't (or perhaps can't) be implemented? To me the intent seems clear and I've tried but I can't see any ambiguity it might create. I'm sure there are some good reasons (or something that I'm missing) and hopefully someone can point it out to me.
So, why can’t an operation be
performed as part of an assignment?
UPDATE:
I understand why this doesn't work. IE: I have a method that expects some parameter and I am calling a method that doesn't return anything - but you are missing my point.... I see that code as two statements one is myCollection (IE: An instance) and the second is "invoke this method".
Here is a more complete example:
public class Stock
{
public Guid ID { get; set; }
public string Description { get; set; }
}
public class StockList : List<Stock>
{
public void SomeSortOperation() { }
}
public void SomeMethod(StockList stockList)
{
}
StockList myList = new StockList();
SomeMethod(myList.SomeSortOperation());
It looks like you're trying to use the result of SomeVoidOperation as a method argument (presumably to a method with no arguments) - but presumably you're not, because it's a void method.
It's never a good idea for code to look like it's doing one thing, when it's actually doing another.
EDIT: Okay, no, having seen the edit, I still don't think this is a good idea. You're basically saying that if you try to use a void expression as a method argument, it should actually use some different value, based on the expression. That expression would have to be very carefully defined... for example, would:
Foo(x.MethodReturningBar().MethodReturningVoid());
consider the argument to be the type of x, or Bar (the return type of the intermediate method call)?
Again, you're writing code which looks like it's doing one thing (using the value of the whole expression as an argument) when it's actually doing something else (using the value of part of the expression as an argument). That's simply a bad idea.
If you mean by SomeVoidOperation() that the operation returns no value (void):
You can't pass nothing to a method that expects to get something. You can't cast a nothing to the type that SomeMethod() expects to get.
I believe that you should backtrack a little and try to understand the void type first. See this answer C# void type- safety. I believe this will give more insight in why what you're trying to do doesn't work.
I recently noticed the following code which basically defines a class method
public Func<string, string> SampleMethod = inputParam =>
{
return inputParam.ToUpper();
};
which is the same as doing it in the old fashioned way
public string SampleMethod(string inputParam )
{
return inputParam.ToUpper();
}
My question - why would I prefer the first over the second? My eyes are maybe more trained to understand the second style quicker. I find it similar to the difference between SMS lingo and plain old english.
Those two things are fundamentally different. The former is a field of a delegate type while the latter is really a method. The tiniest difference I can think of is that you can modify the first one dynamically at runtime and assign another method reference to it while the second is fixed.
You shouldn't normally prefer the first over the second if your purpose is to write a simple method for a class in C#.
An example that makes the first extremely fragile:
var c = new SomeClass();
c.SampleMethod = inputParam => inputParam.ToLower();
c.DoSomeTaskThatReliesOnSampleMethodReturningAnUpperCaseString();
c.SampleMethod = null;
c.DoSomeTaskThatCallsSampleMethod(); // NullReferenceException
This style of programming is common in language like Javascript where an object is fundamentally a dynamic creature built upon a simple dictionary.
They are actually not the same at all. The second is a regular member method, that returns ToUpper on the input string.
The first, on the other hand, is a Func member variable, that happens to point to a delegate, that implements the same functionality. However, as this is a method pointer, you can substitute the delegate with any other delegate of the same type at runtime. I.e. you can completely redefine what it means to call this method.
One benefit of the second way is it's better from a unit testing perspective - you can test your class and know that the method will correctly return the uppercase string. With the first method, you can change the method at runtime, so unit testing is much harder.
This isn't really an issue, however I am curious. When I save a string in lets say an DataRow, it is cast to Object. When I want to use it, I have to cast it ToString. As far as I know there are several ways of doing this, first is
string name = (string)DataRowObject["name"]; //valid since I know it's a string
and another one is:
string name = DataRowObject["name"].ToString();
I am interested in what is the difference between both? Is the first more efficient? (This is just a speculation, in my head ToString() method is implemented by some looping mechanism where just casting it "could" be faster, however this is just a "gut feeling" I have).
Is there even a faster / more elegant way of doing this?
Can anyone clear this up for me?
The two are intended for different
purposes. The ToString method of any
object is supposed to return a string
representation of that object. Casting
is quite different, and the 'as' key
word performs a conditional cast, as
has been said. The 'as' key word
basically says "get me a reference of
this type to that object if that
object is this type" while ToString
says "get me a string representation
of that object". The result may be the
same in some cases but the two should
never be considered interchangeable
because, as I said, they exist for
different purposes. If your intention
is to cast then you should always use
a cast, NOT ToString.
from http://www.codeguru.com/forum/showthread.php?t=443873
see also http://bytes.com/groups/net-c/225365-tostring-string-cast
If you know it is a String then by all means cast it to a String. Casting your object is going to be faster than calling a virtual method.
Edit: Here are the results of some benchmarking:
============ Casting vs. virtual method ============
cast 29.884 1.00
tos 33.734 1.13
I used Jon Skeet's BenchmarkHelper like this:
using System;
using BenchmarkHelper;
class Program
{
static void Main()
{
Object input = "Foo";
String output = "Foo";
var results
= TestSuite.Create("Casting vs. virtual method", input, output)
.Add(cast)
.Add(tos)
.RunTests()
.ScaleByBest(ScalingMode.VaryDuration);
results.Display(ResultColumns.NameAndDuration | ResultColumns.Score,
results.FindBest());
}
static String cast(Object o)
{
return (String)o;
}
static String tos(Object o)
{
return o.ToString();
}
}
So it appears that casting is in fact slightly faster than calling ToString().
Basically in your case it is better to leave type cast because .ToString() may hide bugs. For example, your data base schema changed and name is no longer of string type but with .ToString() your code still works. So in this case it is better to use type cast.
Here is implementation of String.ToString() - nothing special =)
public override string ToString()
{
return this;
}
Downcasting is a relatively slow operation since CLR has to perform various runtime type-checks. However, in this particular scenario casting to string is more appropriate than calling ToString() for the sake of consistency (you can't call ToInt32 on object, but cast it to int) and maintanability.
I want to make one more comment
If you are going to use casting: string name = (string)DataRowObject["name"]
you will get an Exception: Unable to cast object of type 'System.DBNull' to type'System.String' in case if the record in the database table has null value.
In this scenario you have to use: string name = DataRowObject["name"].ToString() or
You have to check for null value like
if(!string.IsNullOrEmpty(DataRowObject["name"].ToString()))
{
string name = (string)DataRowObject["name"];
}
else
{
//i.e Write error to the log file
string error = "The database table has a null value";
}
For data object, I suggest you to use "as" keyword like the following code.
string name = DataRowObject["name"] as string;
Please check it before you use value.
if(name != null)
{
// statement for empty string or it has value
}
else
{
// statement for no data in this object.
}
In this case:
string name = DataRowObject["name"].ToString();
since it is a string, I think that the ToString() method of a string object is simple as:
return this;
so IMHO there is no performance penalty.
PS
I'm a Java programmer, so this anwser is only a guess.
ToString() does not perform a cast by default. Its purpose is to return a string that represents the type (e.g. "System.Object").
If you want to avoid casting you could try to think of an implementation that is strongly typed (using generics, for example) and avoids DataRowObject altogether.
I know you mentioned that the Object is a string, but incase you're afraid that the returned object is null, you can also cast using "Convert.ToString(DataRowObject["name"]);" This has the added benefit of returning an empty string (string.empty) if the object is null, to avoid any null reference exceptions (unless of course you want an exception thrown in such cases).