c# delegate and abstract class - c#

I currently have 2 concrete methods in 2 abstract classes. One class contains the current method, while the other contains the legacy method. E.g.
// Class #1
public abstract class ClassCurrent<T> : BaseClass<T> where T : BaseNode, new()
{
public List<T> GetAllRootNodes(int i)
{
//some code
}
}
// Class #2
public abstract class MyClassLegacy<T> : BaseClass<T> where T : BaseNode, new()
{
public List<T> GetAllLeafNodes(int j)
{
//some code
}
}
I want the corresponding method to run in their relative scenarios in the app. I'm planning to write a delegate to handle this. The idea is that I can just call the delegate and write logic in it to handle which method to call depending on which class/project it is called from (at least thats what I think delegates are for and how they are used).
However, I have some questions on that topic (after some googling):
1) Is it possible to have a delegate that knows the 2 (or more) methods that reside in different classes?
2) Is it possible to make a delegate that spawns off abstract classes (like from the above code)? (My guess is a no, since delegates create concrete implementation of the passed-in classes)
3) I tried to write a delegate for the above code. But I'm being technically challenged:
public delegate List<BaseNode> GetAllNodesDelegate(int k);
GetAllNodesDelegate del = new GetAllNodesDelegate(ClassCurrent<BaseNode>.GetAllRootNodes);
I got the following error:
An object reference is required for the non-static field, method, property ClassCurrent<BaseNode>.GetAllRootNodes(int)
I might have misunderstood something... but if I have to manually declare a delegate at the calling class, AND to pass in the function manually as above, then I'm starting to question whether delegate is a good way to handle my problem.
Thanks.

The way you're attempting to use delegates (constructing them with new, declaring a named delegate type) suggests that you're using C# 1. If you're actually using C# 3, it's much easier than that.
Firstly, your delegate type:
public delegate List<BaseNode> GetAllNodesDelegate(int k);
Already exists. It's just:
Func<int, List<BaseNode>>
So you don't need to declare your own version of it.
Secondly, you should think of a delegate as being like an interface with only one method in it, and you can "implement" it on the fly, without having to write a named class. Just write a lambda, or assign a method name directly.
Func<int, List<BaseNode>> getNodesFromInt;
// just assign a compatible method directly
getNodesFromInt = DoSomethingWithArgAndReturnList;
// or bind extra arguments to an incompatible method:
getNodesFromInt = arg => MakeList(arg, "anotherArgument");
// or write the whole thing specially:
getNodesFromInt = arg =>
{
var result = new List<BaseNode>();
result.Add(new BaseNode());
return result;
};
A lambda is of the form (arguments) => { body; }. The arguments are comma-separated. If there's only one, you can omit the parentheses. If it takes no parameters, put a pair of empty parentheses: (). If the body is only one statement long, you can omit the braces. If it's just a single expression, you can omit the braces and the return keyword. In the body, you can refer to practically any variables and methods from the enclosing scope (apart from ref/out parameters to the enclosing method).
There's almost never any need to use new to create a delegate instance. And rarely a need to declare custom delegate types. Use Func for delegates that return a value and Action for delegates that return void.
Whenever the thing you need to pass around is like an object with one method (whether an interface or a class), then use a delegate instead, and you'll be able to avoid a lot of mess.
In particular, avoid defining interfaces with one method. It will just mean that instead of being able to write a lambda to implement that method, you'll have to declare a separate named class for each different implementation, with the pattern:
class Impl : IOneMethod
{
// a bunch of fields
public Impl(a bunch of parameters)
{
// assign all the parameters to their fields
}
public void TheOneMethod()
{
// make use of the fields
}
}
A lambda effectively does all that for you, eliminating such mechanical patterns from your code. You just say:
() => /* same code as in TheOneMethod */
It also has the advantage that you can update variables in the enclosing scope, because you can refer directly to them (instead of working with values copied into fields of a class). Sometimes this can be a disadvantage, if you don't want to modify the values.

You can have a delegate that is initialized with references to different methods depending on some conditions.
Regarding your questions:
1) I'm not sure what you mean under "knows". You can pass any method to the delegate, so if you can write method that "knows" about some other methods than you can do a similar delegate.
2) Again, delegates can be created from any method that can be executed. For example if you have an initialized local variable of type ClassCurrent<T> you can created delegate for any instance method of type ClassCurrent<T>.
3) Delegate can call only the method that actually can be called. I mean that you cannot call ClassCurrent.GetAllRootNodes because GetAllRootNodes is not a static method, so you need an instance of the ClassCurrent to call it.
The delegate can stay in any class that has access to the ClassCurrent and MyClassLegacy.
For example you can create smth like:
class SomeActionAccessor<T>
{
// Declare delegate and fied of delegate type.
public delegate T GetAllNodesDelegate(int i);
private GetAllNodesDelegate getAllNodesDlg;
// Initilaize delegate field somehow, e.g. in constructor.
public SomeActionAccessor(GetAllNodesDelegate getAllNodesDlg)
{
this.getAllNodesDlg = getAllNodesDlg;
}
// Implement the method that calls the delegate.
public T GetAllNodes(int i)
{
return this.getAllNodesDlg(i);
}
}
The delegates can wrap both static and instance method. The only difference is that for creation delegate with instance method you need instance of the class who owns the method.

Let both ClassCurrent and MyClassLegacy implement an interface INodeFetcher:
public interface INodeFetcher<T> {
List<T> GetNodes(int k);
}
For ClassCurrent call the GetAllRootNodes method from the interface's implementation and for MyLegacyClass the GetAllLeaveNodes method.

Why would you want a delegate for this? It sounds overly complex. I would just create a method in a new class that you could instansiate when you needed to call you method. This class could be given some context information to help it decide. Then I would implement logic in the new method that would decide whether to call the current method or the legacy method.
Something like this:
public class CurrentOrLegacySelector<T>
{
public CurrentOrLegacySelector(some type that describe context)
{
// .. do something with the context.
// The context could be a boolean or something more fancy.
}
public List<T> GetNodes(int argument)
{
// Return the result of either current or
// legacy method based on context information
}
}
This would give you a clean wrapper for the methods that is easy to read and understand.

As a variation of the theme suggested by Rune Grimstad I think you could use the strategy pattern (e.g.
Introduction to the GOF Strategy Pattern in C# ).
This would be especially interesting in the case where you cannot change the LegacyClass (and therefore maybe cannot easily use the "interface approach" suggested by Cornelius) and if you are using dependency injection (DI; Dependency injection). DI would (maybe) let you inject the correct implementation (concrete strategy) in the right place.
Strategy:
public interface INodeFetcher<T> {
List<T> GetNodes(int k);
}
Concrete Strategies:
public class CurrentSelector<T> : INodeFetcher<T>
{
public List<T> GetNodes(int argument)
{
// Return the result "current" method
}
}
public class LegacySelector<T> : INodeFetcher<T>
{
public List<T> GetNodes(int argument)
{
// Return the result "legacy" method
}
}
-> Inject/instantiate the correct concrete strategy.
Regards

Related

Using methods from a type passed as a parameter in C#

I'm working in Q#, a quantum programming language based on C#. Quantum operations become C# classes, from which you can do things like
QuantumOperation.run(simulator, param1, param2);
which will use a quantum simulator simulator to run the operation QuantumOperation with the parameters param1 and param2.
I have many different operations which I want to run using different simulators and different parameters. What I would like to do is pass the quantum operation to another method, which will iterate through all the simulators and parameters. Then I can call this method with all the quantum operations I want.
The problem is that - as far as I can tell - a quantum operation is really a class and not an object. So, for example, if I write:
static void someMethod<Qop>(){...}
then I can call this with a quantum operation QuantumOperation as:
someMethod<QuantumOperation>()
and it compiles fine. However, if I try to do something like
static void someMethod<Qop>(Qop quantumOperation){ ...}
someMethod<QuantumOperation>(quantumOperation);
I get an error of "QuantumOperation is a type, which is not valid in the given context" for the second line.
If I try:
static void someMethod<Qop>(...){
...
Qop.Run(...);
...
}
it similarly says: "'Qop' is a type parameter, which is not valid in the given context".
What seems to be happening here is that I'm passing the class as a type. But then when I want to treat the type as a class, I can't. I looked for ways to pass a class as an argument, but I only see ways to do this that will create objects in that class. But I can't use an object, since "Run" is a static method.
(I could try passing an object and getting the class from that, but (a) I don't know if it's possible to create objects of quantum operation classes, and (b) I can only find public Type GetType, which returns a type and not a class, giving the same problem).
Is there any way to pass a class as an argument, then reference static methods of that class, without ever instantiating an object?
Now, maybe I'm asking too much, since, as far as C# is concerned, it's a coincidence that all these classes have a method called "Run". It maybe shouldn't be able to attempt to call methods with the same name from different classes.
Alternatively, I could construct a method for each quantum operation and then pass those methods. The method would look like:
static void QuantumOperationWrapper(QuantumSimulator simulator, Int int_parameter){
QuantumOperation.Run(simulator, in_parameter);
}
I would need to make a new method for each quantum operation, but that's not that bad. Then I can pass this as a delegate or Func to the methods I want. The problem is that the results I want are contained in the QuantumSimulator object. So what I want to do is something like:
QuantumOperationWrapper(simulator, 3);
simulator.GetResults();
But when I do this, the results are empty. My guess is that, somehow, the simulator is being passed by value, or treated as immutable, or something that prevents QuantumOperationWrapper from altering internal parameters of the simulator.
Is there any way to I can ensure that a delegate/Func will alter the internal state of its arguments?
EDIT: I can make a delegate for the Run method, as follows:
public delegate System.Threading.Tasks.Task<Microsoft.Quantum.Simulation.Core.QVoid> RunQop(QCTraceSimulator sim, long n);
Then I can construct static void someMethod(RunQop runner, ...), and pass QuantumOperation.Run as the first argument.
However, I have the same problem, that the QCTraceSimulator I pass as an argument does not keep any of the simulation results it makes when I call this.
So if I understand you correctly you want to execute a bunch of methods with parameters on different simulators. Here is how to do this:
We first off need a List of the operations we want to perform.
var methodList = new List<Func<QCTraceSimulator, long, Task<QVoid>>>
{
QuantumOperation.Run,
// Add more methods here
}
This is a List of Funcs. A Func is a delegate type that represents a method with a parameter and a return value. Here our methods need to look like this to be able to be added to our List:
public Task<QVoid> SomeName(QCTraceSimulator sim, long parameter)
{ ...}
We also need a list of parameters you want to try this with:
var paramsList = new List<long>
{
1,
2,
-2147483648,
2147483647
};
Now we can iterate through these and run our method like so:
public void RunMethodsOnSimulator(QCTraceSimulator sim)
{
// Iterate through every method
foreach (var method in methodList)
{
// Iterate through every parameter
foreach (var parameter in paramsList)
{
// Execute the given method with the given parameter
Task<QVoid> result = method(sim, parameter);
}
}
}
You can now do whatever you want with the result. This will result in every method being called with every parameter once
Please keep in mind that this answer only solves this problem for methods that return a Task<QVoid> and take a QCTraceSimulator and a long as parameter. This solution however avoids having to modify any QuantumOperation classes (and hopefully teaches you a little about delegates)
Here is what the paramsList and the RunMethodsOnSimulator method would like with 2 or more parameters:
methodList = new List<Func<QCTraceSimulator, long, int, Task<QVoid>>>
{
QuantumOperation.Run,
// Add more methods here
}
paramsList = new List<Tuple<long, int>>
{
new Tuple<long, int>(1, 1),
new Tuple<long, int>(2, 1),
new Tuple<long, int>(1, 2),
new Tuple<long, int>(-2147483648, 1)
}
public void RunMethodsOnSimulator(QCTraceSimulator sim)
{
// Iterate through every method
foreach (var method in methodList)
{
// Iterate through every parameter
foreach (var parameter in paramsList)
{
// Execute the given method with the given parameter
Task<QVoid> result = method(sim, parameter.Item1, parameter.Item2);
}
}
}
The way the Q# simulation tests deal with this is by having a method that receives a delegate with some code you want to execute on the simulator, in particular, the simulator unittests have the RunWithMultipleSimulators method that is broadly used in places like CoreTests.cs; this is an example of how it is used:
[Fact]
public void RandomOperation()
{
Helper.RunWithMultipleSimulators((s) =>
{
Circuits.RandomOperationTest.Run(s).Wait(); // Throws if it doesn't succeed
});
}
I think you're having two separate problems: you're not getting the results back, and dealing with classes is making looping through different operations difficult. Let me try to address them separately.
Results from running an operation are returned from the Run method, not stored in the simulator. More specifically, if you invoke an operation that returns a Q# int, the return value of the Run method will be Task<long>. You can then use the value property of the task to get the actual result, or use the async/await pattern, whichever you like.
All of the operation classes can be instantiated, and they all implement the ICallable interface. This interface has an Apply method that gets passed the arguments to the operation and returns the (asynchronous) results. Each instance has to get properly instantiated with a reference to the simulator; the easiest way to do this is to call the Get generic method on the simulator instance.
If you look at SimulatorBase.cs, in the implementation of the Run method on line 101, you can see how this is done. In this method, T is the class of the operation; I is the class of the operation input; and O is the class of the operation return value. You could use basically the same code to create a list of objects that you then call Apply on with varying arguments.
I did not understand everything but from the little that I understood you can use a non static wrapper and each wrapper allows accessing to a distinct Qop static class.
static public void TestQop()
{
someMethod(new Qop1(), 0, 0, 0);
someMethod(new Qop2(), 1, 1, 1);
}
static void someMethod<T>(T qop, int simulator, int param1, int param2)
where T : QopBase
{
qop.Run(simulator, param1, param2);
}
abstract class QopBase
{
public abstract void Run(int simulator, int param1, int param2);
}
class Qop1 : QopBase
{
public override void Run(int simulator, int param1, int param2)
{
QuantumOperation1.Run(simulator, param1, param2);
}
}
class Qop2 : QopBase
{
public override void Run(int simulator, int param1, int param2)
{
QuantumOperation2.Run(simulator, param1, param2);
}
}
Calling a method on an object whose type is generically defined requires you to use a generic constraint which ensures that the used generic type defines the expected method.
At its core, this relies on polymorphism to ensure that even though the specific type can vary, it is known that all usable generic types (which can be limited via constraints) contain this specific method you wish to call.
Static classes and methods lack this feature. They cannot inherit, nor can they implement interfaces, nor can you pass them via method parameters (and trying to do it via generic is not the solution). There is no way to create an "inheritance-like" link between two static methods of two different static classes; even if the methods have the same signature otherwise.
Are there other ways? Yes. In order of preferability:
(1) The straightforward and clean solution is avoiding statics and instead use instanced classes. If you are able to do this, this is the superior option.
(2) If you can't avoid statics, you can still wrap your static in an instanced wrapper, e.g.:
public class IWrapper
{
void DoTheThing(int foo);
}
public QuantumOperationWrapper : IWrapper
{
public void DoTheThing(int foo)
{
QuantumOperationWrapper.Run(foo);
}
}
public OtherStaticOperationWrapper : IWrapper
{
public void DoTheThing(int foo)
{
OtherStaticOperationWrapper.Run(foo);
}
}
This effectively "unstatics" the static code, in a way that you can now rely on the knowledge that all your wrappers implement/inherit the common BaseWrapper and thus both implement the DoTheThing method.
Your generic method can then rely on this:
public void DoTheGenericThing<T>(T obj) where T : IWrapper
{
obj.DoTheThing(123);
}
Note: In this particular case you don't even need generics to begin with. I assume you don't really need generics in this case, but since the answer can apply to both generic and non-generic cases, I've left the generic parameter in the solution. There may be specific cases in which you still need to use generics, though I suspect this is not one of them.
(3) A third but very dirty option is to use reflection to call the method anyway and just assume you never pass in a type which does not have the expected static method. But this is a really bad practice approach which will be fraught with bugs, it will be nigh impossible to debug, and it's absolutely not refactor-friendly.
Maybe you can try to deal with the situation using Interfaces. Something like that:
public interface IQuantumOperation
{
void Run();
void Run(MyFancyClazz simulator, MyFancyParam param1, MyFancyParam param2);
//And other possible methods
}
Then you can make use of this Interface as a type parameter's contract
static void someMethod<Qop>(Qop myQopParameter) where Qop : IQuantumOperation
{
...
//Now you can call your Run method
myQopParameter.Run(...);
...
//Or other fancy Run method with parameters like below
myQopParameter.Run(simulator, param1, param2);
}
Finally make sure that your QuantumOperation class implements the IQuantumOperation interface

What is the exact meaning of delegate() method in C#?

I am pretty new in C# (I came from Java) and I am working on a SharePoint project.
I have the following doubt related to this method in my code:
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
lock (this)
{
try
{
SPSecurity.RunWithElevatedPrivileges(delegate ()
{
SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
DeleteExistingJob(JobName, parentWebApp);
});
}
catch (Exception ex)
{
throw ex;
}
}
}
as you can see this code is executed into delegate() {...} "block":
SPSecurity.RunWithElevatedPrivileges(delegate ()
{
SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
DeleteExistingJob(JobName, parentWebApp);
});
What exactly means this delegate() method?
Reading here: https://learn.microsoft.com/it-it/dotnet/csharp/language-reference/keywords/delegate
it seems to me that it somethings like a way to declare an "anonymous" method where the implementation of this method is the code into the {...} block.
Is this the correct interpretation or am I missing something?
In case it is correct what is the pourpose of this delegate() method? Why I am not declaring the code into a classic method? What is it exact pourpose?
As per the documentation you referred to, the delegate keyword is used for two purposes:
To declare a delegate type
To create an anonymous method which is converted into a delegate instance
Now you could write all the code in an anonymous method in a regular method and then use a method group conversion to create a delegate instance, but that can often be annoying - particularly if you want to use any local variables or parameters in the anonymous method.
So that's why you'd use an anonymous method - or in anything from C# 3 onwards, you're more likely to use a lambda expression instead.
Consider how you'd have to create the delegate in your example if you didn't use an anonymous method or lambda expression. You'd need to write something like this:
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
lock (this)
{
// Note: try/catch removed as it's pointless here, unless you're
// *trying* to obscure the stack trace in case of an exception
JobDeletionHelper helper = new JobDeletionHelper(properties);
// Note that we're using a method group conversion here - we're not
// invoking the method. We're creating a delegate which will invoke
// the method when the delegate is invoked.
SPSecurity.RunWithElevatedPrivileges(helper.DeleteJob);
}
}
// We need this extra class because the properties parameter is *captured*
// by the anonymous method
class JobDeletionHelper
{
private SPFeatureReceiverProperties properties;
internal JobDeletionHelper(SPFeatureReceiverProperties properties)
{
this.properties = properties;
}
public void DeleteJob()
{
// This is the code that was within the anonymous method
SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
DeleteExistingJob(JobName, parentWebApp);
}
}
If you're asking about the purpose of delegates themselves, that's a slightly bigger topic - but in a nutshell, it's the ability to represent executable code as an object, so it can be passed to other code to execute. (You can think of a delegate type as being like a single-method interface, if that's useful.)
it seems to me that it somethings like a way to declare an "anonymous"
method where the implementation of this method is the code into the
{...} block.
Yes, that is on point!
In case it is correct what is the pourpose of this delegate() method?
Why I am not declaring the code into a classic method? What is it
exact pourpose?
Since you mentioned that you came from Java you can think of passing a delegate(){ ... } as passing an anonymous class in java to some extent.
In Java, an anonymous class enables you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name. Use them if you need to use a local class only once.
For example, In Java prior to JDK8 you could do:
btn.setOnAction(new EventHandler<ActionEvent>() { //<--- implementation
#Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
or as of JDK8:
btn.setOnAction(e -> System.out.println("Hello World!"));
Likewise in C# delegate () {...} is allowing you to pass an implementation i.e some behaviour on the fly.
It was common pattern a while back to use delegate () {...} but now you're most likely to use a lambda equivalent of () => { ... }
You may find these posts of interest:
when & why to use delegates?
Where do I use delegates?

How to use generics to handle type-specific configurations in an Action<IBuilder<T>>?

I am trying to implement a complex builder to help my testing context. To do that I refactored my code to have a method :
public TestContext Add<T>(Action<IBuilder<T>> configurator) where T : class, new()
{
IBuilder<T> builder = CreateBuilderOf<T>();
configurator(builder);
T item = builder.GetItem();
RepositoryOf<T>().Insert(item);
SetCurrent(item);
return this;
}
The problem arises when I need to specify the configuration when calling the method :
TestContext.Instance.Add<Person>(personBuilder => ((PersonBuilder)personBuilder).Name("SMITH"));
I need to be able to use type specific methods in the configurator, which are implemented by the concrete builders, such as :
public PersonBuilder : IBuilder<Person>
{
private Person Item;
public PersonBuilder() { Item = new Person(); }
public Name(string mame) { Item.Name = name; }
public Person GetItem() { return Item; }
}
Apparently, passing an Action<PersonBuilder> as an Action<IBuilder<Person>> is not allowed, even though PersonBuilder implements IBuilder<Person>, hence the cast.
I would very much like to either :
Need not to cast inside the lambda but rather at the start of it, e.g.
(PersonBuilder personBuilder) => personBuilder.Name("SMITH"), but that boils down to being an instance of Action<PersonBuilder> and therefore is equally invalid;
Use a function such as BuildSimplePerson(PersonBuilder builder) in Add's argument : Add<Person>(BuildSimplePerson)
I think I can do a type casting through two BuildSimplePersons implementations such as :
private void BuildSimplePerson(IBuilder<Person> builder)
{
BuildSimplePerson(builder as PersonBuilder);
}
private void BuildSimplePerson(PersonBuilder builder)
{
builder.Name("SMITH");
}
But that is not really an elegant solution.
I also realize passing Action<PersonBuilder> as an Action<IBuilder<Person>> is incorrect because we don't know if the argument to that function will truly be a PersonBuilder or any other implementation of IBuilder<Person>.
How can I do better ?
As my comment already states, the problem is that your current code assumes that CreateBuilderOf<T> returns a PersonBuilder but it could actually return anything that implements IBuilder<Person> in which case your cast would fail.
Your code looks like it is generic, but in fact, it is not. You always want to work on the concrete class (PersonBuilder) and not on the general interface IBuilder<Person>.
My understanding is, that you want one generic Add<T> method to avoid having to repeat that code inside it for each type.
Here is my approach:
public TestContext Add<T>(IBuilder<T> builder) where T : class, new()
{
T item = builder.GetItem();
RepositoryOf<T>().Insert(item);
SetCurrent(item);
return this;
}
You would call it like this:
TestContext.Instance.Add<Person>(CreatePersonBuilder().Name("SMITH"));
Obviously, you would need to have a CreateXBuilder method for each type that you want to be able to add. However, I think you already have this at least implicitly, because I would assume that your CreateBuilderOf<T> method is one huge switch statement anyway.
If you don't want to create such methods, another approach to get the builder would be a generic method like so:
CreateBuilder<PersonBuilder>()
But really, this is actually nothing more than a new PersonBuilder(), so you actually could simply go with
TestContext.Instance.Add<Person>(new PersonBuilder().Name("SMITH"));
The Configure method would be very similar:
TestContext.Instance.Configure<Person>(id, p => new PersonBuilder(p).Name("SMITH"));
This would pass the ID, which the Configure method would use to look up the object, which in turn is passed to the callback. So the second parameter of Configure would not be a Action<IBuilder<T>> but an Action<T>.
This approach has another advantage over your existing code:
Your existing code assumes not just that PersonBuilder will be the implementation used for IBuilder<Person>. No, your code also assumes that it has a constructor without parameters and one which takes a Person. These assumptions are impossible for the compiler to verify.
With the code I showed above, a builder implementation could take additional parameters without problems and the compiler would verify that everything is alright.

c# Is it possible to supply a lambda when an interface is required?

In some class method, A, I need to call a library method B, which takes as an IProgress<Object> as a parameter.
Normally, I might either implement IProgress<Object> as part of class where A resides, and then pass "this" to method B. Or perhaps I might create a new class whose only purpose is to implement IProgress<Object> and handle it correctly-- then in this case I'd create an instance of that class and pass it to B.
But what I really want is to have my implementation of IProgress<Object> to appear right inside the method in which I'm calling B, so that there's less of a visual disconnect between the calling code, and the IProgress<Object> implementation. (I consider my implementation of IProgress to be kind of a private, non-shared detail of the calling method and thus I don't want my implementation of IProgress<Object> to be in a whole separate method of perhaps a whole other class).
What I've been trying to do is use a lambda in which I will define my short progress handling, and then somehow pass this lambda to B, like this:
method in class A {
...
Action<Object> Report = (m) => { // do something useful with m };
B(Report)
}
method B(IProgress<Object> reporter) {
reporter.Report(some object)
}
Of course, I know why this won't work as is - B is wanting an object that implements IProgress<Object> and I'm handing it an Action object instead.
Is there any way to achieve what I'm trying to achieve? (IE have my implementation if IProgress<Object> appear inside method A?
Delegates cannot implement interfaces (directly).
Two good options come to mind:
Change the definition of the method that you're calling to take a delegate types instead of an IProgress type. (If possible; this would be the preferable option)
Create a new type that implements the interface that you need and takes a delegate as a parameter to implement that functionality.
And example of #2, while dependent on the interface, might look something like this:
interface IProgress<T>
{
void doStuff(T param);
}
class LambdaProgress<T> : IProgress<T>
{
Action<T> action;
public LambdaProgress(Action<T> action)
{
this.action = action;
}
public void doStuff(T param)
{
action(param);
}
}
then you'd be able to do something like:
B(new LambdaProgress<Object>(obj => ...));
No, you can't supply a lambda when an interface is required.
But you can supply an anonymous object by using impromptu-interface.
This example is from its project page:
//Anonymous Class
var anon = new
{
Prop1 = "Test",
Prop2 = 42L,
Prop3 = Guid.NewGuid(),
Meth1 = Return<bool>.Arguments<int>(it => it > 5)
}
var myInterface = anon.ActLike<IMyInterface>();
In your example this can be:
A
{
// Create an anonymous object.
var anonymous = new
{
// Define a method that needs an "object" parameter and returns nothing.
Report = Return.Arguments<object>(m =>
{
// Do whatever you want to do when Report is called.
})
}
// Get your anonymous object as an IProgress<Object>.
var obj = anonymous.ActLike<IProgress<Object>>
// Call B.
B(obj);
}
Assuming that your IProgress<object> interface has just the single void Report(object) method, and that you control the API, you could simply redefine the methods that currently require a parameter of type IProgress<object> to instead require a new delegate type:
public delegate void ProgressReportDelegate(object someObject);
Then your example could change to:
method in class A {
...
Action<Object> Report = (m) => { // do something useful with m };
B(Report)
}
method B(ProgressReportDelegate reporter) {
reporter(someObject);
}
For more complex interfaces, or where you don't control the API (and so can't change a method to take the delegate rather than on object implementing that interface), this isn't really an option, but it would appear to work in your case.
I believe José is the only valid answer here and helped me with the same problem.
From the question Michael want to call a method "B" but use a lambda instead of implementing the IProgress interface:
method B(IProgress<Object> reporter) {
reporter.Report(some object)
}
To do this without creating a new class that needs to implement the IProgress interface, the Progress class can be used as it implements the IProgress interface already. Just create a lambda that looks like this and pass that into your method:
var reporter = new Progress<int>((x) =>
{
// call your own methods that use the reported value here
MyProgressMethod.SetProgress(x);
});
And now you can use this in your methods as per question above:
B(reporter);
Or if you want to do this in one line:
B(new Progress<int>((x) => { progress.SetProgress(action, x); }));
With .NET 4.5 you can use Progress class
Example:
var reporter = new Progress<Object>((m) => {
// do something useful with m
});
B(reporter);

How to access static methods of generic types

public class BusinessObjects<O>
where O : BusinessObject
{
void SomeMethod()
{
var s = O.MyStaticMethod(); // <- How to do this?
}
}
public class BusinessObject
{
public static string MyStaticMethod()
{
return "blah";
}
}
Is there a correct object oriented approach to accomplishing this or will I need to resort to reflection?
EDIT: I went too far in trying to oversimplify this for the question and left out an important point. MyStaticMethod uses reflection and needs the derived type to return the correct results. However, I just realized another flaw in my design which is that I can't have a static virtual method and I think that's what I would need.
Looks like I need to find another approach to this problem altogether.
You can't access a static method through a generic type parameter even if it's constrained to a type. Just use the constrained class directly
var s = BusinessObject.MyStaticMethod();
Note: If you're looking to call the static method based on the instantiated type of O that's not possible without reflection. Generics in .Net statically bind to methods at compile time (unlike say C++ which binds at instantiation time). Since there is no way to bind statically to a static method on the instantiated type, this is just not possible. Virtual methods are a bit different because you can statically bind to a virtual method and then let dynamic dispatch call the correct method on the instantiated type.
The reason you can't reference the static member like this:
O.MyStaticMethod();
Is because you don't know what type O is. Yes, it inherits from BusinessObject, but static members are not inherited between types, so you can only reference MyStaticMethod from BusinessObject.
If you are forcing O to inherit from BusinessObject, why not just call it like this:
void SomeMethod()
{
var s = BusinessObject.MyStaticMethod(); // <- How to do this?
}

Categories

Resources