For some reason I have a feeling only Jon Skeet would know the answer to this but it's worth a shot.
I have this method stub which is used as a proxy to generate commands.
public static void SetCommand<T>(string commandName, Action<T> execution)
where T : new()
{
//Omitted unimportant
}
I have a function which is calling this code, but the behavior differs depending on how it's called.
If I call the code by explictly declaring an Action all of the parameter can resolve fine
Action<ClassDeclarationOptions> test = (t) => { };
SetCommand(GENERATE_CLASS_COMMAND, test);
However if I declare a function to represent my action
public static void GenerateClass(ClassDeclarationOptions classOptions)
{
}
Then I need to explictly declare the parameter when passing it to the function like so:
SetCommand<ClassDeclarationOptions>(GENERATE_CLASS_COMMAND, Commands.GenerateClass);
Can someone explain why the compiler cannot resolve my Generic Parameter from Method Definition
Let's say there's an overload on Commands.GenerateClass that takes a different parameter type, for example:
public static void GenerateClass(SomeOtherClass stuff)
{
}
Now there's no way for the compiler to figure out which GenerateClass method to use. However, as soon as you specify the type parameter the ambiguity goes away.
So even if you had a single method and the compiler inferred the type arguments, you could add that second method later on and break existing code without even realising it. Much safer just to force code to be explicit.
Related
I don't know if this is possible in C#. But here's what I'm trying to do:
An interface that declares a method with a completion block / callback / lambda / whatever you want to call it. Seems simple enough. But, here's a first attempt:
namespace N {
interface MyInterface {
delegate void CompletionBlock();
void doSomething(CompletionBlock completionBlock);
}
}
But interfaces can't declare delegates. Ok, how about this?
namespace N {
public delegate void CompletionBlock();
interface MyInterface {
void doSomething(CompletionBlock completionBlock);
}
}
Sure that works, but now, say I declare another type of CompletionBlock, one which takes an argument for instance. I can't call the type CompletionBlock because it'll clash with the above type, if inside the same namespace.
Then there's Action and Func. But even Action takes a parameter, and I want no parameters. So Action doesn't seem like a viable candidate. Really, all I want, is a way of inlining the concept of "anonymous block as long as the signature is void(void). Something like this:
namespace N {
interface MyInterface {
void doSomething(typeof(()=>) completionBlock);
}
}
But lambdas don't really have a type in C#. Do they at least have signatures?
Basically, is there any way around this?
In Objective-C, for instance, blocks are of type NSBlock, even though their signatures themselves are not easily accessible, but one can create a method that takes a block with a specific signature. For instance:
- (void)doSomething:(void(^)(void))completionBlock
Would be a method that takes a block with no parameters and no return type, and you'd call the method like so, for instance:
[obj doSomething:^(){your block code}];
Then there's Action and Func. But even Action takes a parameter, and I want no parameters. So Action doesn't seem like a viable candidate.
If you use Action (not Action<T>), it does not take parameters.
namespace N {
interface MyInterface {
void doSomething(Action completionBlock);
}
}
This allows you to write:
yourInstance.doSomething(() => DoWhatever(foo));
Or, if DoWhatever is void DoWhatever(), just:
yourInstance.doSomething(DoWhatever);
Use Action<T> or Func<TResult> or one of their siblings or just Action in your case.
Action<...> don't return anything where as Func<..., TResult> do.
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.
Can someone explain to me why in the following the 3rd invocation of DoSomething is invalid?
( Error message is "The name 'DoSomething' does not exist in the current context" )
public class A { }
public class B : A
{
public void WhyNotDirect()
{
var a = new A();
a.DoSomething(); // OK
this.DoSomething(); // OK
DoSomething(); // ?? Why Not
}
}
public static class A_Ext
{
public static void DoSomething(this A a)
{
Console.WriteLine("OK");
}
}
Extension methods can be invoked like other static methods.
Change it to A_Ext.DoSomething(this).
If you're asking why it isn't implicitly invoked on this, the answer is that that's the way the spec was written. I would assume that the reason is that calling it without a qualifier would be too misleading.
Because DoSomething takes a parameter.
DoSomething(a) would be legal.
Edit
I read the question a bit wrong here.
Since your calling it a a normal static method, and not a extension method, you need to prefic with the class name.
So A_Ext.DoSomething(a); will work.
If you call it like a normal static method, all the same rules apply.
Your second variant works because B inhetits A, and therefore you still end up calling it as an extension method, but the third does not.
sorry about the first version above that does not work. I'll leave it to keep the comment relevant.
Extension methods are still static methods, not true instance calls. In order for this to work you would need specific context using instance method syntax (from Extension Methods (C# Programming Guide))
In your code you invoke the extension
method with instance method syntax.
However, the intermediate language
(IL) generated by the compiler
translates your code into a call on
the static method. Therefore, the
principle of encapsulation is not
really being violated. In fact,
extension methods cannot access
private variables in the type they are
extending.
So while normally, both syntaxes would work, the second is without explicit context, and it would seem that the IL generated can't obtain the context implicitly.
DoSomething requires an instance of A to do anything, and without a qualifier, the compiler can't see which DoSomething you need to invoke. It doesn't know to check in A_Ext for your method unless you qualify it with this.
I want to implement a method that will find stuff in my custom class. It should work like generic collections work - i pass a pointer to a function, and the method will iterate through all it has to look in, apply this function, and if it returns true return the found item.
I'd like to pass function pointer as a parameter, but i dont want to declare delegate types.
I know i can do something like:
delegate bool Foo(MyClass)
MyClass MyMethod(Foo x)
{...}
And i know i can do something like this:
MyClass MyMethod(Func<MyClass,bool> x)
But can i do it without declaring a delegate type and without using built in stuff like Func<> which has limits on how many parameters i can have (in case of Func, one...)
You can just use delegate if you want, although it's a bit old school :)
public void TestInvokeDelegate()
{
InvokeDelegate( new TestDelegate(ShowMessage), "hello" );
}
public void InvokeDelegate(TestDelegate del, string message)
{
del(message);
}
public delegate void TestDelegate(string message);
public void ShowMessage(string message)
{
Debug.WriteLine(message);
}
You can allways pass in a Delegate and call DynamicInvoke on it:
MyClass MyMethod(Delegate x) {
// ...
x.DynamicInvoke(....);
// ...
}
It looks like you are trying to implement the Visitor pattern. In this case visiting methods usually have only one parameter - the instance to visit. Having additional arguments passed around conceals the use of the pattern and makes it harder to reason about. This article shows you one way to implement it in C#.
The key is to create a visitor class that will encapsulate all the parameters that affect the visiting process. This way you don't need to pass anythnig other than an object in question in the visiting method - everything else lives in instance fields.
However, if you really want to pass some additional parameters in the method and don't know what type they can have, there are ways to do that. More or less standard approach in .NET world is to use a delegate without return value and with single parameter of type object, the example would be ParameterizedThreadStart delegate:
public delegate void ParameterizedThreadStart(
Object obj
)
This way you get to pass only one parameter in the delegate, but it could be anything - an instance of a class, an array or null, if you end up not needing additional arguments after all. The downside of this approach is that it requires type casting which can lead to runtime errors.
While refactoring some code, I came across this strange compile error:
The constructor call needs to be dynamically dispatched, but cannot be because it is part of a constructor initializer. Consider casting the dynamic arguments.
It seems to occur when trying to call base methods/constructors that take dynamic arguments. For example:
class ClassA
{
public ClassA(dynamic test)
{
Console.WriteLine("ClassA");
}
}
class ClassB : ClassA
{
public ClassB(dynamic test)
: base(test)
{
Console.WriteLine("ClassB");
}
}
It works if I cast the argument to object, like this:
public ClassB(dynamic test)
: base((object)test)
So, I'm a little confused. Why do I have to put this nasty cast in - why can't the compiler figure out what I mean?
The constructor chain has to be determined for certain at compile-time - the compiler has to pick an overload so that it can create valid IL. Whereas normally overload resolution (e.g. for method calls) can be deferred until execution time, that doesn't work for chained constructor calls.
EDIT: In "normal" C# code (before C# 4, basically), all overload resolution is performed at compile-time. However, when a member invocation involves a dynamic value, that is resolved at execution time. For example consider this:
using System;
class Program
{
static void Foo(int x)
{
Console.WriteLine("int!");
}
static void Foo(string x)
{
Console.WriteLine("string!");
}
static void Main(string[] args)
{
dynamic d = 10;
Foo(d);
}
}
The compiler doesn't emit a direct call to Foo here - it can't, because in the call Foo(d) it doesn't know which overload it would resolve to. Instead it emits code which does a sort of "just in time" mini-compilation to resolve the overload with the actual type of the value of d at execution time.
Now that doesn't work for constructor chaining, as valid IL has to contain a call to a specific base class constructor. (I don't know whether the dynamic version can't even be expressed in IL, or whether it can, but the result would be unverifiable.)
You could argue that the C# compiler should be able to tell that there's only actually one visible constructor which can be called, and that constructor will always be available... but once you start down that road, you end up with a language which is very complicated to specify. The C# designers usually take the position of having simpler rules which occasionally aren't as powerful as you'd like them to be.