Replies: 14 comments 1 reply
-
There's another potential use case for this. If functors are supported, I propose also allowing to "derive" from delegate types. e.g.:
This will allow explicit closing on state where it's needed. |
Beta Was this translation helpful? Give feedback.
-
What is wrong with just using indexers and |
Beta Was this translation helpful? Give feedback.
-
@gafter My first thought too, but won't work for The ability to derive a class from a delegate is the first thing that has interested me about this proposal. |
Beta Was this translation helpful? Give feedback.
-
@gafter I don't mind having to explicitly call |
Beta Was this translation helpful? Give feedback.
-
@gafter Besides the point that indexers must return a value there's also semantics people tend to think about indexers as "accessors" or "mutators" of collections and so they are more related to properties and they are in fact kind of properties so abusing indexers to mean a method call is a bit odd and can lead to confusion. It's like abusing operators to mean something else, a citation from the guidelines about operators overloading:
Also, the Indexers guideline suggests the following:
Functors may not have parameters at all or may have more than a single parameter.
Functors may have parameters as user-defined types. Updated this post and the OP with more details. |
Beta Was this translation helpful? Give feedback.
-
@bbarry Calling an |
Beta Was this translation helpful? Give feedback.
-
C++ has |
Beta Was this translation helpful? Give feedback.
-
Would the type actually inherit from the delegate type? In other words, for your example, what would If the type was to actually inherit from the delegate type, that would require changes to the base library (since delegate types are currently |
Beta Was this translation helpful? Give feedback.
-
@svick Well, I guess that this is why he said "potential use-case for this" but we aren't really discussing implementation details atm so the changes it will require can be discussed after we nail the use-cases for this. :) |
Beta Was this translation helpful? Give feedback.
-
Would be nice it it could, but I wouldn't want the feature to be held back by BCL (& CLR) changes. The inheritance difference is new, but it'll only become apparent once you work at reflection level. For all other purposes ( We can also name them I do feel they're necessary for completeness if we have functors, as they're the counterpart of them; |
Beta Was this translation helpful? Give feedback.
-
@YaakovDavis It will probably need a separate proposal though. :) |
Beta Was this translation helpful? Give feedback.
-
I just had the same idea while playing with implementations of some group theory concepts. If there is an instance with an var x = a(); // a.Invoke();
var y = a(foo); // a.Invoke(foo);
var z = a(foo, bar); // a.Invoke(foo, bar); One example, where I use the public sealed class SaveCustomerUoW
{
Func<CustomersContext> CustomersContextFactory { get; }
public SaveCustomerUoW(Func<CustomersContext> customersContextFactory)
{
CustomersContextFactory = customersContextFactory;
}
public void Invoke(Customer customer)
{
using(var context = CustomersContextFactory())
{
context.Customers.Add(customer);
context.SaveChanges();
}
}
} // dependency injection of the UoW object
public SomeClass(AddCustomerUoW addCustomer)
{
AddCustomer = addCustomer;
}
SaveCustomerUoW SaveCustomer { get; } Usage: // currently
SaveCustomer.Invoke(customer);
// with proposed syntax:
SaveCustomer(customer); The advantage here is that the UoW can be more easily thought of as a function or method, rather than as an object. It also saves some typing and improves the readability of the code. |
Beta Was this translation helpful? Give feedback.
-
How about using an approach like indexers, and just changing class Foo
{
public TR this(T1 p1, T2, p2, ...)
{
// ...
}
} |
Beta Was this translation helpful? Give feedback.
-
Summary
Generialize delegate invocation for user-defined classes/structs.
Motivation
Generalization of delegate invocation in order to support the following use-cases:
Support state where delegates and methods cannot be used.
Support hierarchies where delegates and methods cannot be used.
This can be thought as a more "primitive" type of delegates to some extent.
Detailed design
A class that implements the
Invoke
method will allow instances to be invoked using the same syntax used for delegate invocation.Example:
Today, we must explicitly call the method
Invoke
like so:With this proposal we could reduce the noise quite a bit.
Please let's not go into what the names of the class should be as in verbs vs nouns or whatever because this is really debatable.
Drawbacks
@JeffreySax made a comment about one possible drawback in the previous proposal so I'll just cite him:
Alternatives
As pointed out above, we can always define whatever method to execute the operation like this:
There's no real drawbacks here besides the needless verbosity and the fact that it looks awkward.
In the previous proposal @vbcodec suggested to use indexers like this:
Known limitations of indexers:
They cannot have void as their return type.
They cannot be parameterless.
Another thing about indexers that can be an annoyance and even lead to confusion is that they really feel out of place both syntactically and semantically, i.e, indexers are properties and as such the syntax are inherited from properties and finally the semantics are such that people associate them with accessing or mutating collections.
Prototype
Prototype available by @orthoxerox
Beta Was this translation helpful? Give feedback.
All reactions