For example, if you go to IDbSetExtensions.AddOrUpdate Method (IDbSet, Expression>, TEntity[]) page on MSDN -- http://msdn.microsoft.com/en-us/library/hh846514(v=vs.103).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1 --, you see that it takes three params. IDbSet, Expression and TEntity.
But what people usually write is like the below.
AddOrUpdate(item => new{item.Text}, itemArray); -- for the "seed method" within migrations.
My questions are:
How come there's only 2 params provided, not 3 and it's still ok?
What will be the difference between "AddOrUpdate(item => item.Text, itemArray)" and "AddOrUpdate(item => new{item.Text}, itemArray)" where first one there's no new operator.
When you're programming, do I need to know what every single line (within a project template) is doing?
I started project using template, so I don't have complete understanding of what it's doing but it sure takes time to dissect the whole template.
Method you're looking at is an extension method. That's why you can call it with the first parameter missing.
If you look closely, you can see that the method is static, which means it should be called using the class name, which is IDbSetExtensions.AddOrUpdate. However, because it is an extension method (this modifier in front of the first method argument makes that happen), you can call it as if it was an instance method of the type of the first method argument, in this case IDbSet<TEntity>.
Read more about extension methods on MSDN: Extension Methods (C# Programming Guide)
For AddOrUpdate(item => item.Text, itemArray) generic type TObject will get inferred to be whatever the type of item.Text is (probably a string). For AddOrUpdate(item => new{item.Text}, itemArray) is will be inferred as anonymous type, with one property.
You definitely should.
How come there's only 2 params provided, not 3 and it's still ok?
The method call AddOrUpdate(item => new{item.Text}, itemArray) only passes two parameters, which is the same number of parameters as AddOrUpdate(item => item.Text, itemArray).
What's the difference
The method call with new {item.Text} returns an anonymous type with (assuming item.Text is a string) a string property called Text that has the value of item.Text. The other method returns a string.
Do you need to know what every single line is doing?
No. Only, the compiler needs to know. But it will help you write software if you know what the code does.
Related
So I have this assignment for class and the professor is asking me to do a method that contains two parameters but no return and he also wants us to create another method with one parameter with no return.
Can somebody explain to me what he means by this?
Can a parameter in a method have no return?
No. You are misreading the assignment. It is not: "(a method (with a parameter (that has no return)))". It's "(a method (with a parameter) (that has no return))". The "has no return" modifies "method", because methods are things that return. Parameters are not.
Can somebody explain to me what he means by this?
He means:
Make a method
The method takes one parameter
The method returns no value
I note that the question is somewhat ambiguous because it is legal in C# for a method with a regular body to have a return type but no return statements. Exercise: can you come up with such a method that is legal in C#?
(Edit: rewritten the whole answer)
The formatting in the assignment mislead you.
The four boxes in the table are independent.
Task 1. Create a method that meets the following criteria.
Method Name: DisplayQuestionMessage
Parameters:
Whether the user's guess was correct: true or false
The correct answer
Return: None
What the method does: This method will output 1 of 2 ...
I have an assignment from my teacher and I think that the task in not possible but he insists that it can be done: basically I need to create o method WriteSum that adds two integer numbers and the method is called by him in the main method while I must write the WriteSum method code in a class: He insists that the method must be called like this: WriteSum(22+24) with return value 46.
Is this possible???
From what I know in C# method arguments are given with commas between them so his correct code for calling the method should be WriteSum(22,24)???
His code is like this:
string n = Calculator.WriteSum(22+24);
Console.WriteLine(n);
Console.Read();
And I have to write the "WriteSum" method in a class Calculator.
You are right: C# will evaluate the expression 22+24 before calling your method. In other words, WriteSum(22+24) will behave exactly like WriteSum(46), i.e., it will
call a single-parameter method with the name WriteSum and
pass the integer expression 46 as the argument.
Thus, the requirements as stated in your question cannot be fulfilled. As others have mentioned in the comments, it is possible that your instructor actually meant to assign you one of the following tasks:
Just write the value of the parameter that has been passed. In that case, however, the method should be called WriteInt instead of WriteSum and the implementation would be trivial.
If the method takes a string argument (i.e. WriteSum("22+24")), you'd need to parse the string, extract the summands, add them, and print (or return) the result. This does sound like a realistic task given to a student.
In any case, you should really clarify the requirements before you start to implement anything.
Have have big problem with Visual Studio 2013 and 2015. In one class, i have defined this two methods:
public List<T> LoadData<T>(string connectionStringName = "", string optWherePart = "", params object[] parameter)
public List<T> LoadData<T>(string optWherePart, params object[] parameter)
I only want to call the second method like this:
....LoadData<Config_Info>("ConfigName LIKE 'Version' AND UserName LIKE '' AND PlugInName Like ?", parameter: ProductName);
If i go to definition in Visual Studio 2013, i come to the second method declaration, but in Visual Studio 2015, i come to the first. Both solutions are
absolutly identically.
Even the compiled result is different, so if i compile the same solution with VS 2015, the program stops working.
This is a very strange behaviour.
Does any one has an idea, what the differences are?
This is based on the C# 5 specification, but since the C# 6 specification doesn't appear to have been published yet that's the best I can do. It's also an attempt to invoke Cunningham's Law.
As a preliminary, in the language of s7.5.3.1 ("Applicable Function Member") of the spec, both function members are applicable (either of them could be called if the other didn't exist) in their expanded form (the params object[] can't be fulfilled by the string ProductName so is converted to an object argument).
Thus we move on to s7.5.3.2 ("Better Function Member") in order to decide which of the two is the better function to call.
Firstly, a stripped-down argument list A is constructed containing just the argument expressions themselves in the order they appear in the original argument list:
{ string "ConfigName [...]", string ProductName }
Next, [p]arameter lists for each of the candidate function members are constructed in the following way:
The expanded form is used if the function member was applicable only in the expanded form.
Optional parameters with no corresponding arguments are removed from the parameter list
The parameters are reordered so that they occur at the same position as the corresponding argument in the argument list.
This gives us the following:
{ string connectionStringName, object parameter } (optWherePart removed, params expanded)
{ string optWherePart, object parameter } (params expanded)
We then have a sequence of comparisons to make to decide which of these is the better function member. Calling one Mp and one Mq, these go as follows:
If Mp is a non-generic method and Mq is a generic method, then Mp is better than Mq.
No difference here
Otherwise, if Mp is applicable in its normal form and Mq has a params array and is applicable only in its expanded form, then Mp is better than Mq.
No difference here; both are in their expanded form
Otherwise, if Mp has more declared parameters than Mq, then Mp is better than Mq. This can occur if both methods have params arrays and are applicable only in their expanded forms.
Not 100% on this one. Both our argument lists use 2 of the parameters from the original function definitions. I think this is solely meant to distinguish between one case where both arguments went into the same params array and one where one went into the array and one went into a normal argument.
Otherwise if all parameters of Mp have a corresponding argument whereas default arguments need to be substituted for at least one optional parameter in Mq then Mp is better than Mq.
Aha! Our first argument list is missing optWherePart, which needed a default argument, so the second argument list is better! So VS2015 is wrong!
... but wait. What does this last bullet even mean? Mp and Mq are specifically parameter lists where [o]ptional parameters with no corresponding arguments are removed. There is no way either of them could not have a corresponding argument because if they didn't, they'd have been removed.
In conclusion, I can't tell whether this is a bug in the old compiler, the new compiler... or the C# specification.
I've found a blog post by SLaks that also seems to think the old behaviour was a bug. The blog states that Roslyn had fixed this by making the compiler fail, and that's not what I see any more. Maybe they changed their minds?
Edit: Update! My Roslyn bug report resulted in a change to the compiler to ensure that, in this case, the second overload is picked. This appears to be because of the default arguments need to be substituted wording above. I still think the spec is ambiguous, so I'm disappointed that only a code change was made (and not a spec change, or even a discussion about why the second overload is the better one), but at least the VS2015 runtime beaviour is now the same as it was in VS2013.
I made a method to loop and clear all textbox controls in my form.
Controls.OfType<TextBox>()
.ToList()
.ForEach(tb => tb.Clear());
This works just fine, but I figured that since the first argument passed to any instance method is always a reference to the instance that I should be able to write it like this
Controls.OfType<TextBox>()
.ToList()
.ForEach(TextBox.Clear);
Unfortunately that doesn't actually work, and I don't quite understand why..
It would work if TextBox.Clear was a static method with a TextBox parameter; but instead, it's an instance method with no parameters, so the compiler can't automatically transform it to an Action<TextBox>.
Note that the CLR does support open-instance delegates (you can create one with the Delegate.CreateDelegate method), but the C# language doesn't support it.
Here's how to create an open-instance delegate that will invoke TextBox.Clear on its argument:
var action = (Action<TextBox>)Delegate.CreateDelegate(
typeof(Action<TextBox>),
null,
typeof(TextBox).GetMethod("Clear"));
The this parameter is implicit, not explicit. Foreach is expecting a method with an explicit parameter, not an implicit one.
As for why the C# language team didn't implement this feature, you'll have to ask them. They of course could have designed the language to support this, if they wanted to. There's no real point in us speculating as to why they didn't.
I'm using BitFactory logging, which exposes a bunch of methods like this:
public void LogWarning(object aCategory, object anObject)
I've got an extension method that makes this a bit nicer for our logging needs:
public static void LogWarning(this CompositeLogger logger,
string message = "", params object[] parameters)
Which just wraps up some common logging operations, and means I can log like:
Logging.LogWarning("Something bad happened to the {0}. Id was {1}",foo,bar);
But when I only have one string in my params object[], then my extension method won't be called, instead the original method will be chosen.
Apart from naming my method something else, is there a way I can stop this from happening?
The rules about how overloaded methods are resolved to one (or an error) are complex (the C# specification is included with Visual Studio for all the gory details).
But there is one simple rule: extension methods are only considered if there is no possible member that can be called.
Because the signature of two objects will accept any two parameters, any call with two parameters will match that member. Thus no extension methods will considered as possibilities.
You could pass a third parameter (eg. String.Empty) and not use it in the format.
Or, and I suspect this is better, to avoid possible interactions with additions to the library (variable length argument list methods are prone to this) rename to LogWarningFormat (akin to the naming of StringBuffer.AppendFormat).
PS. there is no point having a default for the message parameter: it will never used unless you pass no arguments: but that would log nothing.
Declared methods are always preceding extension methods.
If you want to call the extension regardless of the declared method, you have to call it as a regular static method, of the class that declared it.
eg:
LoggerExtensions.LogWarning(Logging, "Something bad happened to the {0}. Id was {1}",foo,bar);
I assume that the extension is declared in a class named LoggerExtensions
Provided that I think a method with a different name is the way to go (easier to read and maintain), as a workaround you could specify parameters as a named parameter:
logger.LogWarning("Something bad happened to the {0}.", parameters: "foo");