Declare a function supporting both Void and IEnumerator - c#

I was wondering if there is a way to declare a method (in an interface for example) that supports the use of IEnumerator and Void, without the need to implement both in the subclasses?
public void Start()
public IEnumerator Start()
this is related to my other question: Hold or Wait while Coroutine finishes
i noticed in the Unity context, the default Start() method seems to allow for both.

You can't do that because those methods would have the same signature and the CSC woudn't be able to figure out which method should be statically bound for each call. e.g.:
public class TestClass
{
public int FooMethod()
{
return 1;
}
public void FooMethod()
{
return;
}
public string FooMethod()
{
return "foo";
}
}
static void Main()
{
TestClass test = new TestClass();
Console.WriteLine(test.FooMethod()); // which FooMethod should be called here?
}
A method's return type is not considered as part of its signature. What you can do is overload the same method with a different signature to return a different type. Also, in the case of an additional method that differs only in returning void, you can always choose not to use the result returned by the original method.
The case with interfaces is similar. when a class implements an interface it is agreeing to a protocol, that it implements that interface's behaviour which is what consumers of your class expect. So you cannot partly agree with an interface. Although you can throw a NotImplementedException in your implementations you have to at least define all members, which leads to the same problem mentioned in the above example: the C# compiler will not be able to statically bind your method calls and your code will fail to compile.
You can solve your problem by reconsidering your design.

The short answer is no.
The closest you could get to this is using generics, however that would not work for a void, sorry.
public T Start()

One function name + combination of parameters can only be declared once, thus can only have one output.

Related

Base class Task<> has no empty constructor

I have a C# code
private class EvaluationTask : Task<Solution> {
private Problem problem_;
private Solution solution_;
public EvaluationTask(Problem problem, Solution solution)
{
problem_ = problem;
solution_ = solution;
}
}
Now, I am getting error System.Threading.Tasks.Task<> does not contain constructor that takes 0 arguments. From previous answers posted, I found that one has to define empty constructor in the base class. But since my base class is Task<>, how do I add an empty constructor to it?
Any help would be highly appreciated!
Edit: I have to inherit task<> because I have to use the method EvaluationTask in a code:
taskList_ = new List<Task<Solution>>();
taskList_.Add(new MultithreadedEvaluator.EvaluationTask (problem_, solution));
I don't know about task composition, so if it is necessary can anyone help with that? Or if by any way I can avoid inheriting Task and still implement taskList_.Add()?
When you inherit from a class, in your constructors you need to call any of the constructors of the base class. In your case, since you aren't calling any constructor, the compiler try to call a parameterless constructor of the base class, but Task<> haven't a parameterless constructor.
As you can read here, inheriting from Task<> probably isn't a good idea, but you can do something like this:
class EvaluationTask : Task<Evaluation>
{
public EvaluationTask()
: base(DoWork) { }
private static Evaluation DoWork()
{
//...
}
}
When using Task<T>, you must supply the Func<> or Action<> delegate (i.e., function pointer to the desired work to perform) as a constructor argument. It is indeed somewhat unfortunate that there isn't any constructor which lets you bypass this requirement and supply the delegate at a later time (yet obviously still prior to calling Start()), since this severely hampers the ability to extend the Task and Task<TResult> classes via inheritance altogether.
The reason it's a crippling omission is that no delegate you supply as a constructor argument can possibly directly incorporate a reference to the instance you are trying to construct, since that instance (again, obviously) doesn't exist yet, chicken/egg style.
Hence #Arturo's answer, which shows that you can, in fact, supply a static delegate, but since such a delegate has no obvious way of referencing one particular Task instance, it essentially defeats the purpose of inheriting from Task in the first place.
--- reflection disclaimer ---I've been using this technique in my own projects for years on .NET Framework 4.7 (desktop) with no problems whatsoever, but please note that code which uses reflection to access non-public behavior is subject to breakage if the .NET internals change in a later version. You have been warned.
Here's a more flexible workaround for the problem, a general-purpose abstract base class for Task<TResult> which allows you to provide the desired work code in the normal way for derived type hierarchies: as an instance method override. This is a reflection solution; the way it works is to provide a dummy "placeholder" delegate to the base constructor call, but then immediately in the constructor body, swap it out for the "real," desired abstract instance work method, which at that point is no longer unknowable or rather unbindable.
abstract class TaskBase<TResult> : Task<TResult>
{
readonly static FieldInfo m_action =
typeof(Task).GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic);
readonly static Func<TResult> _dummy = () => default;
public TaskBase(CancellationToken ct, TaskCreationOptions opts)
: base(_dummy, ct, opts) =>
m_action.SetValue(this, (Func<TResult>)function);
public TaskBase(CancellationToken ct)
: this(ct, TaskCreationOptions.None)
{ }
public TaskBase(TaskCreationOptions opts)
: this(default, opts)
{ }
public TaskBase()
: this(default, TaskCreationOptions.None)
{ }
protected abstract TResult function(); // <-- override with your work code
};
To use this, simply inherit from TaskBase<TResult>, and override the abstract method function() to implement your task work logic. There is no need for a version of this base class where the work function accepts a AsyncState argument/parameter(s), since you can simply declare all the relevant context for the specific work instance as additional instance fields (and instance methods, and instance properties...) in your derived class. So the constructor variations I declared exactly match those provided by Task<TResult>, but minus the 'function' and 'state' arguments. And finally, don't forget to call Start() when your packaged work instance is ready to go!
The above is a actually a simplified version of the TaskBase<TResult> code I've had much success with. My enhanced version avoids creating the Func<TResult> delegate which must be created for each TaskBase instance in order to "wrap" the C# method function() as an instance delegate. Instead of initially providing a 'dummy' delegate to the base constructor, I always provide (the same) static delegate, a singleton which acts as a "thunk" that universally reinterprets, or "upcasts" a Task<TResult>'s AsyncState object as a pertinent TaskBase<TResult> instance, and then calls function() directly on that instance. Like so:
static Func<Object,TResult> thunk = obj => ((TaskBase<TResult>)obj).function();
So fn_redirect is the only "excess" delegate we need to create once at startup, and this singleton is always passed-in as the base constructor work delegate. Now as with that constructor argument, the "async state" object is also only passed in as a constructor argument and normally cannot later be changed. We don't need a "dummy" in this approach, because you can--and should--pass in 'null' for state. Similar to before we use reflection to set a field, but this time it's m_stateObject field instead of m_action, to replace the 'null' value we just installed for the instance this pointer:
public TaskBase(CancellationToken ct, TaskCreationOptions opts)
: base(thunk, default(Object), ct, opts)
{
m_stateObject.SetValue(this, this);
}
Voila, allocating one extra delegate for each TaskBase instance is avoided. Finally, recall that there are no adverse loss of capability when co-opting the state object for the purpose of this enhancement because as I mentioned earlier, the whole AsyncObject argument-passing mechanism is unnecessary when you entirely control the derived class you are writing.
Here is an inheritable class that inherits from Task<T>, and allows delayed assignment of the task's function. The constructor takes no arguments. The function is assigned by the property Function.
public class FlexibleTask<T> : Task<T>
{
private readonly Helper _helper;
public Func<T> Function { set { _helper.SetFunction(value); } }
public FlexibleTask() : base(GetFunction())
{
this._helper = TempHelper;
TempHelper = null;
}
private static Func<T> GetFunction()
{
Func<T> function = Default;
var helper = new Helper();
helper.SetFunction = f => function = f;
TempHelper = helper;
return () => function();
}
private static readonly Func<T> Default = () =>
throw new InvalidOperationException("Function is not set.");
[ThreadStatic] private static Helper TempHelper;
private class Helper
{
public Action<Func<T>> SetFunction {get; set;}
}
}
Usage Example:
public class EvaluationTask : FlexibleTask<int>
{
}
var task = new EvaluationTask();
task.Function = () => 13;
task.Start();
var result = await task;
Console.WriteLine($"Result: {result}");
Output:
Result: 13

C#: Custom IEnumerator?

This is a message pertaining to C# in Unity, but I'm assuming general C# knowledge will apply.
Take the following code:
class myClass
{
IEnumerator myEnumerator;
public IEnumerator theEnumerator()
{
int i = 0;
while (true)
{
Debug.Log(i++);
yield return null;
}
}
public void Update()
{
if (myEnumerator == null) { myEnumerator = theEnumerator(); }
myEnumerator.MoveNext();
}
}
If I instance that class, then call "Update" once per frame, I get the following output in the log:
0
1
2
3
4...
That works fine, however I want to implement some custom functionality in the IEnumerator itself. But if I create the following:
public class myIEnumerator : IEnumerator
{
public int myCustValue;
public void myCustFunction(){}
}
and then update the oringal class, replacing "IEnumerator" the "myIEnumerator", I get the following error:
The body of `myClass.theEnumerator()' cannot be an iterator block because `myIEnumerator ' is not an iterator interface type
What am I doing wrong here, and how can I make my own custom IEnumerator?
You can only use yield within a method whose return type is IEnumerator, IEnumerable, IEnumerator<T>, or IEnumerable<T>. You can't change the return type of the method to a type that implements one of those interfaces, that doesn't make sense.
The reason for this is that the C# compiler generates a special class that implements one of those 4 interfaces (actually it implements both IEnumerator and IEnumerable or the generic versions thereof) and an instance of that compiler generated class is what actually gets returned from the method. By changing the return type you're trying to say that the compiler will create an instance of your class that will do the enumeration. But it can't do that, because it doesn't actually know anything about your class (and in fact your class might not even enumerate correctly).
I'm not familiar with Unity but I think you have to implement the IEnumerator interface. The methods MoveNext()and Reset()are missing.
Have a look at the IEnumerator Interface

The call is ambiguous between the following methods or properties (one static and one non-static)

Why am I not allowed to have a static and non-static methods with the same signature?
Let's say I have a class like this
public class TestClass
{
public object thing { get; set; }
public TestClass()
{
}
public TestClass(object thing)
{
this.thing = thing;
}
public static TestClass ConvertTestClass(object thing)
{
return new TestClass(thing);
}
public TestClass ConvertTestClass(object thing)
{
this.thing = thing;
return this;
}
}
and I try to use it like this
public class SomeOtherClass
{
public SomeOtherClass()
{
TestClass tc = TestClass.ConvertTestClass(new object());
TestClass tc2 = new TestClass();
tc2.ConvertTestClass(new object());
}
}
I get the following errors on TestClass.ConvertTestClass(new object());
The call is ambiguous between the following methods or properties: 'TestClass.ConvertTestClass(object)' and 'TestClass.ConvertTestClass(object)'
and these errors on tc2.ConvertTestClass(new object());
The call is ambiguous between the following methods or properties: 'TestClass.ConvertTestClass(object)' and 'TestClass.ConvertTestClass(object)'
Member 'TestClass.ConvertTestClass(object)' cannot be accessed with an instance reference; qualify it with a type name instead
Can the compiler really not tell the difference between the static and non static versions of that method or am I missing something here?
I am not using ReSharper (which seemed to be the root of a similar problem in other questions).
Its giving you an error, so its a safe bet that the compiler can't, or won't, discern between the two methods.
Its probably a bad idea to do this kind of overload anyways, as it's unclear which method you are intending to invoke, but if that isn't enough, the C# 5 specification defines a method signature like this (Section 3.6):
The signature of a method consists of the name of the method, the
number of type parameters and the type and kind (value, reference, or
output) of each of its formal parameters, considered in the order left
to right. For these purposes, any type parameter of the method that
occurs in the type of a formal parameter is identified not by its
name, but by its ordinal position in the type argument list of the
method. The signature of a method specifically does not include the
return type, the params modifier that may be specified for the
right-most parameter, nor the optional type parameter constraints.
It doesn't explicitly mention static, but it also doesn't include it as part of the definition of a "signature". Thus, its fair to assume that by the spec, a method overload cannot differ only in the fact that it is static or instanced.
I'd write this as a comment however it's easier to make this point in a proper editor.
I think you're only thinking about the logic of calling methods on the class externally i.e. from another class. Within the class methods with the same signature only differing by static doesn't make any sense. e.g you have a class with two methods as follows
public class MyClass
{
public static void HellowWorld()
{
Console.WriteLine("Hello World!");
}
public void HellowWorld()
{
Console.WriteLine("Howdy World!");
}
public void Greet()
{
HellowWorld();
}
}
When compiling you'll see as long as one of the methods is commented out it compiles without errors. You should be able to alternate the commented out method and compile the class succesfully. Indicating there's no way of differentiating which method should be called within the scope of the class.
You could argue that within the class you should be forced to use the same syntax to call a static method as you do externally e.g.
MyClass.HelloWorld();
However, this would defy scoping logic used throughout C#, why should you need to specify the class name within a class? I think such a change would also create ambiguity where the was none, and to do so now would of course break a lot of code out there.
I think the compiler logic as it is makes perfect sense.

C# Method Overload and Extension Methods [duplicate]

There have been occasions where I would want to override a method in a class with an extension method. Is there any way to do that in C#?
For example:
public static class StringExtension
{
public static int GetHashCode(this string inStr)
{
return MyHash(inStr);
}
}
A case where I've wanted to do this is to be able to store a hash of a string into a database and have that same value be used by all the classes that use the string class's hash (i.e. Dictionary, etc.) Since the built-in .NET hashing algorithm is not guaranteed to be compatible from one version of the framework to the next, I want to replace it with my own.
There are other cases I've run into where I'd want to override a class method with an extension method as well so it's not just specific to the string class or the GetHashCode method.
I know I could do this with subclassing off an existing class but it would be handy to be able to do it with an extension in a lot of cases.
No; an extension method never takes priority over an instance method with a suitable signature, and never participates in polymorphism (GetHashCode is a virtual method).
If the method has a different signature, then it can be done -- so in your case: no.
But otherwise you need to use inheritance to do what you are looking for.
As far as I know the answer is no, because an extension method is not an instance.It's more like an intellisense facility to me that let you call a static method using an instance of a class.
I think a solution to your problem can be an interceptor that intercepts the execution of a specific method (e.g. GetHashCode()) and do something else.To use such an interceptor (like the one Castle Project provides) all objects should be instansiated using an object factory (or an IoC container in Castle) so that thier interfaces can be intercepted through a dynamic proxy generated in runtime.(Caslte also lets you intercept virtual members of classes)
I have found a way to invoke an extension method with the same signature as a class method, however it does not seem very elegant. When playing around with extension methods I noticed some undocumented behavior. Sample code:
public static class TestableExtensions
{
public static string GetDesc(this ITestable ele)
{
return "Extension GetDesc";
}
public static void ValDesc(this ITestable ele, string choice)
{
if (choice == "ext def")
{
Console.WriteLine($"Base.Ext.Ext.GetDesc: {ele.GetDesc()}");
}
else if (choice == "ext base" && ele is BaseTest b)
{
Console.WriteLine($"Base.Ext.Base.GetDesc: {b.BaseFunc()}");
}
}
public static string ExtFunc(this ITestable ele)
{
return ele.GetDesc();
}
public static void ExtAction(this ITestable ele, string choice)
{
ele.ValDesc(choice);
}
}
public interface ITestable
{
}
public class BaseTest : ITestable
{
public string GetDesc()
{
return "Base GetDesc";
}
public void ValDesc(string choice)
{
if (choice == "")
{
Console.WriteLine($"Base.GetDesc: {GetDesc()}");
}
else if (choice == "ext")
{
Console.WriteLine($"Base.Ext.GetDesc: {this.ExtFunc()}");
}
else
{
this.ExtAction(choice);
}
}
public string BaseFunc()
{
return GetDesc();
}
}
What I noticed was that if I called a second method from inside an extension method, it would call the extension method that matched the signature even if there was a class method that also matched the signature. For example in the code above, when I call ExtFunc(), which in turn calls ele.GetDesc(), I get the return string "Extension GetDesc" instead of the string "Base GetDesc" that we would expect.
Testing the code:
var bt = new BaseTest();
bt.ValDesc("");
//Output is Base.GetDesc: Base GetDesc
bt.ValDesc("ext");
//Output is Base.Ext.GetDesc: Extension GetDesc
bt.ValDesc("ext def");
//Output is Base.Ext.Ext.GetDesc: Extension GetDesc
bt.ValDesc("ext base");
//Output is Base.Ext.Base.GetDesc: Base GetDesc
This allows you to bounce back and forth between class methods and extension methods at will, but requires the addition of duplicate "pass-through" methods to get you into the "scope" you desire. I am calling it scope here for lack of a better word. Hopefully someone can let me know what it is actually called.
You might have guessed by my "pass-through" method names that I also toyed with the idea of passing delegates to them in the hopes that a single method or two could act as a pass-through for multiple methods with the same signature. Unfortunately it was not to be as once the delegate was unpacked it always chose the class method over the extension method even from inside another extension method. "Scope" no longer mattered. I have not used Action and Func delegates very much though so maybe someone more experienced could figure that part out.

Why do we have to explicitly specify "this" when invoking an extension method from within a method of a class being extended?

public class StoreController : Controller
{
public string Index()
{
// implicitly specified instance does not work
//return GetMemberName();
// must specify this explicitly
return this.GetMemberName();
}
}
public static class Utilities
{
public static string GetMemberName(this Controller caller,
[CallerMemberName] string memberName = "")
{
return caller.GetType().FullName + "." + memberName;
}
}
Why do we have to explicitly specify this when invoking an extension method from within a method of a class being extended?
In my mental model, we usually can omit this such as when we initialize fields, for example.
An extension method is technically not a method attached to your class.
yourClass.ExtensionMethod() isn't the same as yourClass.ClassMethod().
Basically, what you are doing is getting a convenient way of doing this:
ExtensionMethod(YourClass yourClass) {
//do something
return yourClass;
}
That is my understanding of an extension method. It's a convenient way of calling a method against a class you can't change. So, that's why you can't just call it without this. It's not a class method.
Extension method is just a syntactic sugar to call a static method. Tthis line of code return this.GetMemberName(); is actually convert to a call to static method like Utilities.GetMemberName(this);
As you can see, you have to send this to the static method and that is the reason why you need this keyword.
Without being present at the design board meeting where this was decided it's hard to say why it's like that.
In this text I use method or instance method in the sense of a function associated with a specific object instance and I use function in a mathematical sense. A function receives a number of arguments and creates a result (which is potentially void)
If we do not consider virtual methods which are more complex because the actual function to be called is determined runtime then any and all method calls are syntactic sugar. If we have two methods defined below
internal static class Extensions {
public static string FooEx(this MyClass self){
return self.ToString();
}
}
internal class MyClass {
public string Bar(){
var s1 = Foo();
var s2 = this.FooEx();
}
private string Foo(){
return ToString();
}
}
Then both will be translated to a function call where the first (and only) argument in both cases will be the object identified by this. If you are doubtful about this then look at the IL produced for any call to an instance method and you will notice there's an extra argument compared to the declaration in code. This argument is the thisreference, which is always passed as the first argument to an instance method.
So in the case of an instance method the compiler still need to determine which object to pass as the first argument to the function. That is exactly the same it has to do if you are calling an extension method without this which also means that can't be the real reason why you have to use this in front of an extension method.
In the compiler for Marvin, a compiler build on top of the Mono compiler I had to do a similar trick as C# does with extension methods and wondered why the specs require the this
The real reason why the compiler enforces you to use this before an extension method is that the specs says so. What the reason behind that decision is would need the attention of some one like #EricLippert who where probably there when they decided on that requirement

Categories