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");
Related
for example, there are bunch of overloads of method:
public void MyLongFunctionName(string arg1,...) ...
public void MyLongFunctionName(int arg1,...) ...
//.... many different argument types
To make a shortcut of that long function, i used i.e. my() :
public void my(string arg1,...) ...
public void my(int arg1,...) ...
....
however, is something like this possible to make my() as a shortcut of MyLongFunctionName() , without defining bunch of my() methods (like above) ?
for example, in PHP you can copy function, like :
$my = MyLongFunctionName(arg1, arg2....);
//execute
$my(arg1, arg2....)
P.S. Note to all downvoters and duplicate-markers:
this topic is not duplicate, because that referred topic doesnt answer the question at all. It executes plain function, and even says, that it is not alias at all:
so, that topic doesnt solve the problem. instead, I want to mirror(a.k.a. ALIAS) whole overloads of specific method with i.e. my(), which can accept variation of parameters. so, please stop mindless downvotings of what you dont read.
I'm afraid what you are asking is not possible.
What you want is a kind of delegate for a whole bunch of methods. It's called a method group.
A method group is a set of overloaded methods resulting from a member lookup (ยง7.4).
For example something.ToString is a method group. It may contain one or more methods, depending on whether ToString has overloads for this specific class.
This is a compile time construct. You cannot put a method group into a variable, like you can with a single function. You can make a delegate from a method group, but that involves getting a specific overload and transforming only that into the delegate.
I've read open source c# code and there is a lot of strange grammar (to me).
They declare method arguments with the this keyword like this:
this object #object
What does it mean?
If I remove 'this' keyword where is before the data type, then will it work differently?
Sounds like an Extension Method.
The # symbol allows the variable name to be the same as a C# keyword - I tend to avoid them like the plague personally.
If you remove the this keyword, it will no longer be an extension method, just a static method. Depending on the calling code syntax, it may no longer compile, for example:
public static class IntegerMethods
{
public static int Add(this int i, int value)
{
return i + value;
}
}
int i = 0;
// This is an "extension method" call, and will only compile against extension methods.
i = i.Add(2);
// This is a standard static method call.
i = IntegerMethods.Add(i, 2);
The compiler will simply translate all "extension method calls" into standard static method calls at any rate, but extension method calls will still only work against valid extension methods as per the this type name syntax.
Some guidelines
These are my own, but I find they are useful.
Discoverability of extension methods can be a problem, so be mindful of the namespace you choose to contain them in. We have very useful stuff under .NET namespaces such as System.Collections or whatever. Less useful but otherwise "common" stuff tends to go under Extensions.<namespace of extended type> such that discoverability is at least consistent via convention.
Try not to extend often used types in broad scope, you don't want MyFabulousExtensionMethod appearing on object throughout your app. If you need to, either constrain the scope (namespace) to be very specific, or bypass extension methods and use a static class directly - these won't pollute the type metadata in IntelliSense.
In extension methods, "this" can be null (due to how they compile into static method calls) so be careful and don't assume that "this" is not null (from the calling side this looks like a successful method call on a null target).
These are optional and not exhaustive, but I find they usually fall under the banner of "good" advice. YMMV.
The 'this type name' syntax is used for extension methods.
For example if I wanted to add a UnCamelCase method to a string (so I could do "HelloWorld".UnCamelCase() to produce "Hello World` - I'd write this:
public static string UnCamelCase(this string text)
{
/*match any instances of a lower case character followed by an upper case
* one, and replace them with the same characters with a space between them*/
return Regex.Replace(text, "([a-z])([A-Z])", "$1 $2");
}
this string text means the specific instance of the string that you're working with, and text is the identifier for it.
The # syntax allows for variable names that are ordinarily reserved.
I have the following extension methods for my MessageBus:
public static class MessageBusMixins
{
public static IDisposable Subscribe<T>(
this IObservable<T> observable,
MessageBus bus)
where T:class
{
...
}
public static IDisposable Subscribe<T>(
this IObservable<Maybe<T>> observable,
MessageBus bus)
{
...
}
}
which compiles fine. However when I try to use it:
IObservable<Maybe<string>> source = ...;
MessageBus bus = ...;
source.Subscribe(bus);
I get the error that neither of the two candidate methods
are most specific. However I thought that Maybe<T> would
be more specific than T or is that not correct?
EDIT
It gets curiouser because if I call the extension method
explicitly then:
MessageBus.SubscribeTo(source, bus);
Then it works and picks the correct method.
Well, you can fix it by specifying the type argument:
source.Subscribe<string>(bus);
... as that's now only the second method is applicable.
Otherwise, the compiler could call either of:
source.Subscribe<string>(bus);
source.Subscribe<Maybe<string>>(bus);
If you think the first is more specific than the second, you'll have to find the rule in the C# specification which says so :) It's not an unreasonable expectation, but I don't think the normal "more specific" conversions apply to type parameters as well as regular parameters.
So for example, in section 7.5.3.2 of the C# 4 spec ("Better Function Member") there a rule about:
Otherwise if MP has more specific parameter types than MQ, then MP is better than MQ. [... lots of details about less/more specific ...]
... but there's no similar point about type parameters. (The second about normal parameters talks about type arguments, but that's within the parameter types themselves.)
Another alternative is to simply give the methods different names. Do they have subtly different behaviour? If so, why not make that really obvious via the naming? You really don't want someone to get the wrong behaviour just because they were surprised about which overload was called.
Method overloading allows us to define many methods with the same name but with a different set of parameters ( thus with the same name but different signature ).
Are these two methods overloaded?
class A
{
public static void MyMethod<T>(T myVal) { }
public static void MyMethod(int myVal) { }
}
EDIT:
Shouldn't statement A<int>.MyMethod(myInt); throw an error, since constructed type A<int> has two methods with the same name and same signature?
Are the two methods overloaded?
Yes.
Shouldn't statement A<int>.MyMethod(myInt); throw an error, since constructed type A<int> has two methods with the same signature?
The question doesn't make sense; A is not a generic type as you have declared it. Perhaps you meant to ask:
Should the statement A.MyMethod(myInt); cause the compiler to report an error, since there are two ambiguous candidate methods?
No. As others have said, overload resolution prefers the non-generic version in this case. See below for more details.
Or perhaps you meant to ask:
Should the declaration of type A be illegal in the first place, since in some sense it has two methods with the same signature, MyMethod and MyMethod<int>?
No. The type A is perfectly legal. The generic arity is part of the signature. So there are not two methods with the same signature because the first has generic arity zero, the second has generic arity one.
Or perhaps you meant to ask:
class G<T>
{
public static void M(T t) {}
public static void M(int t) {}
}
Generic type G<T> can be constructed such that it has two methods with the same signature. Is it legal to declare such a type?
Yes, it is legal to declare such a type. It is usually a bad idea, but it is legal.
You might then retort:
But my copy of the C# 2.0 specification as published by Addison-Wesley states on page 479 "Two function members declared with the same names ... must have have parameter types such that no closed constructed type could have two members with the same name and signature." What's up with that?
When C# 2.0 was originally designed that was the plan. However, then the designers realized that this desirable pattern would be made illegal:
class C<T>
{
public C(T t) { ... } // Create a C<T> from a given T
public C(Stream s) { ... } // Deserialize a C<T> from disk
}
And now we say sorry buddy, because you could say C<Stream>, causing two constructors to unify, the whole class is illegal. That would be unfortunate. Obviously it is unlikely that anyone will ever construct this thing with Stream as the type parameter!
Unfortunately, the spec went to press before the text was updated to the final version. The rule on page 479 is not what we implemented.
Continuing to pose some more questions on your behalf:
So what happens if you call G<int>.M(123) or, in the original example, if you call A.MyMethod(123)?
When overload resolution is faced with two methods that have identical signatures due to generic construction then the one that is generic construction is considered to be "less specific" than the one that is "natural". A less specific method loses to a more specific method.
So why is it a bad idea, if overload resolution works?
The situation with A.MyMethod isn't too bad; it is usually pretty easy to unambiguously work out which method is intended. But the situation with G<int>.M(123) is far worse. The CLR rules make this sort of situation "implementation defined behaviour" and therefore any old thing can happen. Technically, the CLR could refuse to verify a program that constructs type G<int>. Or it could crash. In point of fact it does neither; it does the best it can with the bad situation.
Are there any examples of this sort of type construction causing truly implementation-defined behaviour?
Yes. See these articles for details:
https://ericlippert.com/2006/04/05/odious-ambiguous-overloads-part-one/
https://ericlippert.com/2006/04/06/odious-ambiguous-overloads-part-two/
Yes. MyMethod(int myVal) will be called when the type of the parameter is an int, the generic overload will be called for all other parameter arguments, even when the parameter argument is implicitly convertible to (or is a derived class of) the hardcoded type. Overload resolution will go for the best fit, and the generic overload will resolve to an exact match at compile time.
Note: You can explicitly invoke the generic overload and use an int by providing the type parameter in the method call, as Steven Sudit points out in his answer.
short s = 1;
int i = s;
MyMethod(s); // Generic
MyMethod(i); // int
MyMethod((int)s); // int
MyMethod(1); // int
MyMethod<int>(1); // Generic**
MyMethod(1.0); // Generic
// etc.
Yes, they are. They will allow code as such:
A.MyMethod("a string"); // calls the generic version
A.MyMethod(42); // calls the int version
Yes, they are overloaded. The compiler is supposed to prefer explicit method signatures against generic methods if they are available. Beware, however, that if you can avoid this kind of overload you probably should. There have been bug reports with respect to this sort of overload and unexpected behaviors.
https://connect.microsoft.com/VisualStudio/feedback/details/522202/c-3-0-generic-overload-call-resolution-from-within-generic-function
Yes. They have the same name "MyMethod" but different signatures. The C# specification, however, specifically handles this by saying that the compiler will prefer the non-generic version over the generic version, when both are options.
Yes. Off the top of my head, if you call A.MyMethod(1);, it will always run the second method. You'd have to call A.MyMethod<int>(1); to force it to run the first.
The first parameter to a C# extension method is the instance that the extension method was called on. I have adopted an idiom, without seeing it elsewhere, of calling that variable "self". I would not be surprised at all if others are using that as well. Here's an example:
public static void Print(this string self)
{
if(self != null) Console.WriteLine(self);
}
However, I'm starting to see others name that parameter "#this", as follows:
public static void Print(this string #this)
{
if(#this != null) Console.WriteLine(#this);
}
And as a 3rd option, some prefer no idiom at all, saying that "self" and "#this" don't give any information. I think we all agree that sometimes there is a clear, meaningful name for the parameter, specific to its purpose, which is better than "self" or "#this". Some go further and say you can always come up with a more valuable name. So this is another valid point of view.
What other idioms have you seen? What idiom do you prefer, and why?
I name it fairly normally, based on the use. So "source" for the source sequence of a LINQ operator, or "argument"/"parameter" for an extension doing parameter/argument checking, etc.
I don't think it has to be particularly related to "this" or "self" - that doesn't give any extra information about the meaning of the parameter. Surely that's the most important thing.
EDIT: Even in the case where there's not a lot of obvious meaning, I'd prefer some meaning to none. What information is conferred by "self" or "#this"? Merely that it's the first parameter in an extension method - and that information is already obvious by the fact that the parameter is decorated with this. In the example case where theStringToPrint/self option is given, I'd use outputText instead - it conveys everything you need to know about the parameter, IMO.
I name the variable exactly how I would name it if it were a plain old static method. The reason being that it can still be called as a static method and you must consider that use case in your code.
The easiest way to look at this is argument validation. Consider the case where null is passed into your method. You should be doing argument checking and throwing an ArgumentNullException. If it's implemented properly you'll need to put "this" as the argument name like so.
public static void Print(this string #this) {
if ( null == #this ) {
throw new ArgumentNullException("this");
}
...
}
Now someone is coding against your library and suddenly gets an exception dialog which says "this is null". They will be most confused :)
This is a bit of a contrived example, but in general I treat extension methods no different that a plain old static method. I find it makes them easier to reason about.
I have seen obj and val used. I do not like #this. We should try to avoid using keywords. I have never seen self but I like it.
I call it 'target', since the extension method will operate on that parameter.
I believe #this should be avoided as it makes use of the most useless language-specific feature ever seen (#). In fact, anything that can cause confusion or decrease readability such as keywords appearing where they are not keywords should be avoided.
self reminds me of python but could be good for a consistent naming convention as it's clear that it's referring to the instance in use while not requiring some nasty syntactic trickery.
You could do something like this...
public static void Print(this string extended)
{
if(extended != null) Console.WriteLine(extended);
}