I have a generic method that takes a request and provides a response.
public Tres DoSomething<Tres, Treq>(Tres response, Treq request)
{/*stuff*/}
But I don't always want a response for my request, and I don't always want to feed request data to get a response. I also don't want to have to copy and paste methods in their entirety to make minor changes. What I want, is to be able to do this:
public Tre DoSomething<Tres>(Tres response)
{
return DoSomething<Tres, void>(response, null);
}
Is this feasible in some manner? It seems that specifically using void doesn't work, but I'm hoping to find something analogous.
You cannot use void, but you can use object: it is a little inconvenience because your would-be-void functions need to return null, but if it unifies your code, it should be a small price to pay.
This inability to use void as a return type is at least partially responsible for a split between the Func<...> and Action<...> families of generic delegates: had it been possible to return void, all Action<X,Y,Z> would become simply Func<X,Y,Z,void>. Unfortunately, this is not possible.
No, unfortunately not. If void were a "real" type (like unit in F#, for example) life would be a lot simpler in many ways. In particular, we wouldn't need both the Func<T> and Action<T> families - there'd just be Func<void> instead of Action, Func<T, void> instead of Action<T> etc.
It would also make async simpler - there'd be no need for the non-generic Task type at all - we'd just have Task<void>.
Unfortunately, that's not the way the C# or .NET type systems work...
Here is what you can do. As #JohnSkeet said there is no unit type in C#, so make it yourself!
public sealed class ThankYou {
private ThankYou() { }
private readonly static ThankYou bye = new ThankYou();
public static ThankYou Bye { get { return bye; } }
}
Now you can always use Func<..., ThankYou> instead of Action<...>
public ThankYou MethodWithNoResult() {
/* do things */
return ThankYou.Bye;
}
Or use something already made by the Rx team: http://msdn.microsoft.com/en-us/library/system.reactive.unit%28v=VS.103%29.aspx
You could simply use Object as others have suggested. Or Int32 which I have seen some use. Using Int32 introduces a "dummy" number (use 0), but at least you can't put any big and exotic object into an Int32 reference (structs are sealed).
You could also write you own "void" type:
public sealed class MyVoid
{
MyVoid()
{
throw new InvalidOperationException("Don't instantiate MyVoid.");
}
}
MyVoid references are allowed (it's not a static class) but can only be null. The instance constructor is private (and if someone tries to call this private constructor through reflection, an exception will be thrown at them).
Since value tuples were introduced (2017, .NET 4.7), it is maybe natural to use the struct ValueTuple (the 0-tuple, the non-generic variant) instead of such a MyVoid. Its instance has a ToString() that returns "()", so it looks like a zero-tuple. As of the current version of C#, you cannot use the tokens () in code to get an instance. You can use default(ValueTuple) or just default (when the type can be inferred from the context) instead.
I like the idea by Aleksey Bykov above, but it could be simplified a bit
public sealed class Nothing {
public static Nothing AtAll { get { return null; } }
}
As I see no apparent reason why Nothing.AtAll could not just give null
The same idea (or the one by Jeppe Stig Nielsen) is also great for usage with typed classes.
E.g. if the type is only used to describe the arguments to a procedure/function passed as an argument to some method, and it itself does not take any arguments.
(You will still need to either make a dummy wrapper or to allow an optional "Nothing". But IMHO the class usage looks nice with myClass<Nothing> )
void myProcWithNoArguments(Nothing Dummy){
myProcWithNoArguments(){
}
or
void myProcWithNoArguments(Nothing Dummy=null){
...
}
void, though a type, is only valid as a return type of a method.
There is no way around this limitation of void.
What I currently do is create custom sealed types with private constructor. This is better than throwing exceptions in the c-tor because you don't have to get until runtime to figure out the situation is incorrect. It is subtly better than returning a static instance because you don't have to allocate even once. It is subtly better than returning static null because it is less verbose on the call side. The only thing the caller can do is give null.
public sealed class Void {
private Void() { }
}
public sealed class None {
private None() { }
}
Related
I want to do all of the same code twice, but just for two different objects. I am getting these objects from a SOAP API (rather outdated one).
I want to avoid writing duplicate code over and over again. I'll be taking my original object and manipulating it a lot (all the same way) the only difference is that the object type is the difference, so that's why I need to make a generic object. I want it to return the same type as it takes as a parameter. I am having an issue that if I do code like this
public static class ParamsHelper<T>
{
public static async Task<T[]> Whatever(T[] rptParams)
{
//do some stuff to rptparams
return rptParams;
}
}
// then I call it like this below:
var params = await ParamsHelper.Whatever<ItemP[]>(new ItemP[]{});
// it says can't convert type ItemP[] to type ItemP[][].
Additionally, I am using LINQ to do all of the manipulating. I would love advice on how to access the object fields (maybe reflection?)
You have to declare the generic type on the method.
public static async Task<T[]> Whatever<T>(T[] rptParams)
The usage generally is implied from usage so you don't have to pass it.
if you do have to pass it, dont make it an array.
ParamsHelper.Whatever<ItemP>(new ItemP[] { });
The following program does not compile, because in the line with the error, the compiler chooses the method with a single T parameter as the resolution, which fails because the List<T> does not fit the generic constraints of a single T. The compiler does not recognize that there is another method that could be used. If I remove the single-T method, the compiler will correctly find the method for many objects.
I've read two blog posts about generic method resolution, one from JonSkeet here and another from Eric Lippert here, but I could not find an explanation or a way to solve my problem.
Obviously, having two methods with different names would work, but I like the fact that you have a single method for those cases.
namespace Test
{
using System.Collections.Generic;
public interface SomeInterface { }
public class SomeImplementation : SomeInterface { }
public static class ExtensionMethods
{
// comment out this line, to make the compiler chose the right method on the line that throws an error below
public static void Method<T>(this T parameter) where T : SomeInterface { }
public static void Method<T>(this IEnumerable<T> parameter) where T : SomeInterface { }
}
class Program
{
static void Main()
{
var instance = new SomeImplementation();
var instances = new List<SomeImplementation>();
// works
instance.Method();
// Error 1 The type 'System.Collections.Generic.List<Test.SomeImplementation>'
// cannot be used as type parameter 'T' in the generic type or method
// 'Test.ExtensionMethods.Method<T>(T)'. There is no implicit reference conversion
// from 'System.Collections.Generic.List<Test.SomeImplementation>' to 'Test.SomeInterface'.
instances.Method();
// works
(instances as IEnumerable<SomeImplementation>).Method();
}
}
}
Method resolution says that closer is better. See the blog post for exact rules.
What does the closer mean? Compiler will see if it can find exact match, if it can't find for some reason it will find next possible compatible methods and so forth.
Let's first make that method compile by removing the SomeInterface constraint.
public static class ExtensionMethods
{
public static void Method<T>(this T parameter) //where T : SomeInterface
{ }
public static void Method<T>(this IEnumerable<T> parameter) //where T : SomeInterface
{ }
}
Now compiler is happy to compile, and do note that both method calls Goes to Method(T) rather than Method(IEnumerable<T>). Why is that?
Because Method(T) is closer in the sense that can take any type as the parameter and also it doesn't require any conversion.
Why is Method(IEnumerable<T>) not closer?
It is because you have the compile time type of the variable as List<T>, so it needs a reference conversion from List<T> to IEnumerable<T>. Which is closer but far from doing no conversions at all.
Back to your question.
Why instances.Method(); doesn't compile?
Again, as said earlier to use Method(IEnumerable<T>) we need some reference conversion, so obviously that's not closer. Now we're left with only one method which is very closer is Method<T>. But the problem is you have constrained it with SomeInterface and clearly List<SomeImplementation>() is not convertible to SomeInterface.
The problem is (am guessing) checking for generic constraints happens after the compiler chooses the closer overload. That invalidates the chosen best overload in this case.
You could easily fix it by changing the static type of the variable to IEnumerable<SomeImplementation> that will work and now you know why.
IEnumerable<SomeImplementation> instances = new List<SomeImplementation>();
Have you tried implementing the first one without generics, as it should behave the same:
public static void Method(this SomeInterface parameter) { /*...*/ }
Or, as Dmitry suggested, by calling the second one the following way:
instances.Method<SomeImplementation>();
But here you need to add the <SomeImplementation> to every call...
While I know you dont want it, I think you should really re-think if method names should be the same. I cannot see how the same name can act on an instance, and collection of such instances. For eg, if your method name is Shoot for T, then the other method should sound like ShootThemAll or something similar.
Or else you should make your assignment slightly different:
IEnumerable<SomeImplementation> instances = new List<SomeImplementation>();
instances.Method(); //now this should work
As a last option, as Dimitry says in comments you have to explicitly specify the type argument.
instances.Method<SomeImplementation>();
Returning multiple things from a method, involves either:
returning an object with properties OR
using the out keyword to simply modify incoming parameters
Is there a benefit to using one system or the other? I have been using objects, but just discovered the out keyword, so wondering if I should bother refactoring.
You shouldn't bother refactoring just to utilize out parameters. Returning a class or struct would be preferred as long as structure is reusable.
A common use for out parameters which I would suggest using is to return a status for a call with that is possible to fail. An example being int.TryParse.
It has the possibility of failing, so returning a bool makes it easy to determing whether or not you should use the out parameter.
Another possible solution to returning multiple values from a method would be to use a Tuple. They can return n number of results. E.g.
public Tuple<bool, bool, string> MyMethod()
{
return new Tuple<bool, bool, string>(false, true, "yep");
}
In general, if the object that you are returning is not used anywhere else outside of the return value of your method or a group of similar methods, it is a good indication that you should refactor. When you need to create a special class simply to be used as a return value of a method, it means that you are working around C#'s inability to return multiple values from a method, so the out keyword may be a very good option for you.
On the other hand, if you use the multi-part return value in other places, such as storing them in collections or passing as arguments to other methods, there's probably no need to refactor, because the return object is meaningful.
Compare these two methods:
interface DictionaryReturn<T> {
T Value {get;}
bool Success {get;}
}
...
class Dictionary<K,V> {
...
public DictionaryReturn<V> TryGetValue(K key) {
...
}
}
or
class Dictionary<K,V> {
...
public bool TryGetValue(K key, out V res) {
...
}
}
The first case introduces a special DictionaryReturn<T> class that provides the value and an indicator that the value was found in the dictionary. There is rarely, if ever, a reason to store or use DictionaryReturn<T> objects outside the call to TryGetValue, so the second option is better. Not surprisingly, it is the second option that the designers of the .NET collections library have implemented.
I prefer to use Object with properties. If you use out keyword, you need to define it in other line. It is not as clear as return Object;
The reason to use out keyword is to ensure that code inside the method always sets a value to the out parameter. It's a compile time check that what you intended to do in the function, you did do.
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.
Is there a way via System.Reflection, System.Diagnostics or other to get a reference to the actual instance that is calling a static method without passing it in to the method itself?
For example, something along these lines
class A
{
public void DoSomething()
{
StaticClass.ExecuteMethod();
}
}
class B
{
public void DoSomething()
{
SomeOtherClass.ExecuteMethod();
}
}
public class SomeOtherClass
{
public static void ExecuteMethod()
{
// Returns an instance of A if called from class A
// or an instance of B if called from class B.
object caller = getCallingInstance();
}
}
I can get the type using System.Diagnostics.StackTrace.GetFrames, but is there a way to get a reference to the actual instance?
I am aware of the issues with reflection and performance, as well as static to static calls, and that this is generally, perhaps even almost univerally, not the right way to approach this. Part of the reason of this question is I was curious if it was doable; we are currently passing the instance in.
ExecuteMethod(instance)
And I just wondered if this was possible and still being able to access the instance.
ExecuteMethod()
#Steve Cooper:
I hadn't considered extension methods. Some variation of that might work.
Consider making the method an extension method. Define it as:
public static StaticExecute(this object instance)
{
// Reference to 'instance'
}
It is called like:
this.StaticExecute();
I can't think of a way to do what you want to do directly, but I can only suggest that if you find something, you watch out for static methods, which won't have one, and anonymous methods, which will have instances of auto-generated classes, which will be a little odd.
I do wonder whether you should just pass the invoking object in as a proper parameter. After all, a static is a hint that this method doesn't depend on anything other than its input parameters. Also note that this method may be a bitch to test, as any test code you write will not have the same invoking object as the running system.
I do not believe you can. Even the StackTrace and StackFrame classes just give you naming information, not access to instances.
I'm not sure exactly why you'd want to do this, but know that even if you could do it it would likely be very slow.
A better solution would be to push the instance to a thread local context before calling ExecuteMethod that you can retrieve within it or just pass the instance.
In the case of a static method calling your static method, there is no calling instance.
Find a different way to accomplish whatever you are trying to do.
Just have ExecuteMethod take an object. Then you have the instance no matter what.
I feel like I'm missing something, here. The static method can be called from literally anywhere. There's no guarantee that a class A or class B instance will appear anywhere in the call stack.
There's got to be a better way to accomplish whatever you're trying to do.