How pass delegate to a method, where delegates are non static? - c#

I'm just beginning understanding delegates, I have a class that implemens IDisposable:
public class MyClass : IDisposable
{
public delegate int DoSomething();
public int Zero() {return 0;}
public int One() {return 1;}
public void Dispose()
{
// Cleanup
}
}
A method (defined in an another class) that is using MyClass:
public class AnotherCLass
{
public static void UseMyClass(MyClass.DoSomething func)
{
using (var mc = new MyClass())
{
// Call the delegate function
mc.func(); // <-------- this is what i should actually call
}
}
}
The actual question: how pass the Zero() function to UseMyClass method? Do I have to create an instance of MyClass (I would like to avoid this...)?
public static void main(string[] args)
{
// Call AnotherClass method, by passing Zero()
// or One() but without instatiate MyCLass
AnotherClass.UseMyClass(??????????);
}

Is your intent that the instance is provided by the caller of the delegate, and not the creator of the delegate? C# does support such an unbound delegate, it's called an open delegate, and the instance becomes a parameter.
You have to use Delegate.CreateDelegate to create an open delegate, something like this:
public class MyClass : IDisposable
{
public delegate int DoSomething();
public int Zero() {return 0;}
public int One() {return 1;}
public void Dispose()
{
// Cleanup
}
}
public class AnotherCLass
{
public static void UseMyClass(Converter<MyClass,int> func)
{
using (var mc = new MyClass())
{
// Call the delegate function
func(mc);
}
}
}
AnotherClass.UseMyClass(
(Converter<MyClass, int>)Delegate.CreateDelegate(
typeof(Converter<MyClass, int>),
typeof(MyClass).GetMethod("One")
)
);
Of course, you can do it much more easily with a shim:
AnotherClass.UseMyClass( mc => mc.One() ); // C# 3 or later
AnotherClass.UseMyClass( delegate(MyClass mc) { return mc.One(); } ); // C# 2

Because it's an instance method, if you want to call it, you need an instance. That's simply how the CLR works. However, there are two options you could go with:
Make the member functions static. If they're as simple as returning a static value, there's no reason for them to be instance methods. However, if you do actually require instance data...
Use a singleton instance. This way you don't need to create a new instance every time you want to call your static method.
You can do the latter like this:
public class MyClass
{
private static MyClass singletonInstance;
public static MyClass SingletonInstance
{
get
{
if (singletonInstance == null)
{
singletonInstance = new MyClass();
}
return singletonInstance;
}
}
// the rest of your class implementation
}
Then, you can call your static method like so:
AnotherClass.UseMyClass(MyClass.SingletonInstance.Zero);

Cant be done without instantiation. Heres how you can do it:
public static void main(string[] args)
{
// Call AnotherClass method, by passing Zero()
// or One() but without instatiate MyCLass
AnotherClass.UseMyClass((new MyClass()).Zero);
}

Related

How to use an interface within a public interface with a main?

//Program.cs
public interface TestVal
{
//Input Param
string Input { get; }
//will return output
TestValRes ValidateRe(string input);
}
class MyClass : ITestVal
{
static void Main(string[] args)
{
var instance = new MyClass();
instance.Run();
}
public void Run()
{
ValidateRe("test");
}
public ITestValRes ValidateRe(string input)
{
return null; // return an instance of a class implementing ITestValRes here.
}
}
//TestvalRes.cs
public interface TestvalRes
{
string Input { get; }
bool IsValid { get; }
}
So I just want to pass a string to the TestVal, do validation and call TestvalRes to return whether it is Valid or not, and if Invalid, why? So the validation will be done in the first public interface - TestVal, however I still need to call it inside the Main(), right?
First off, I'd recommend following C# naming conventions and name your interfaces ITestVal and ITestValRes respectively.
Next, static method cannot call instance methods in the same class (without creating an instance and using that). You need to create an instance of the class and pass control of the application flow to that:
class MyClass : ITestVal
{
static void Main(string[] args)
{
var instance = new MyClass();
instance.Run();
}
public void Run()
{
ValidateRe("test");
}
public ITestValRes ValidateRe(string input)
{
return null; // return an instance of a class implementing ITestValRes here.
}
}

c# generic delegate to manage instantiated objects

I'm trying to figure out how to use a generic delegate to manage my instantiated objects in a game engine.
Here is some pseudo-code to demonstrate what I'm trying to do:
public class ObjectManager
{
public delegate void ObjectManagerEvent <T> (T instantiatedObject);
public ObjectManagerEvent <T> onObjectInstantiated;
public void InstantiateObject (Object objToInstantiate)
{
var obj = SomeInternalInstantiateMethod ();
ObjectManagerEvent _onObjectInstantiated = onObjectInstantiated;
if (_onObjectInstantiated != null)
{
_onObjectInstantiated (obj);
}
}
}
public class Shape : EBehaviour {}
public class Animal : EBehaviour {}
public class DemoShape
{
private void Init ()
{
ObjectManager.onObjectInstantiated += OnObjectInstaniated;
}
public void OnObjectInstaniated (Shape shape)
{
// do something with shape
}
}
public class DemoAnimal
{
private void Init ()
{
ObjectManager.onObjectInstantiated += OnObjectInstaniated;
}
public void OnObjectInstaniated (Animal animal)
{
// do something with animal
}
}
I know that public ObjectManagerEvent <T> onObjectInstantiated (); would throw an error, but I'm just kind of lost on how to achieve what I want.
Any pointers?
First, your delegate syntax is very C# 1.0.
Option 1
You can't do this in a particularly simple and elegant way because in C# you cannot use an open generic type to declare a generic event. The closest that we can do is create a dictionary of objects, each of which has an event, and we can use generic methods to access this dictionary.
I also assume you intend InstantiateObject to create and return a new instance. Here I also assume everything is a class with a parameterless constructor.
public static class ObjectManager
{
public class TypeEvent<T>
{
// Our event handler will accept a parameter of type T and return void
public event Action<T> OnObjectInstantiated;
public void RaiseObjectInstantiated(T obj)
{
OnObjectInstantiated?.Invoke(obj);
}
}
private static Dictionary<Type, object> _typeMap = new Dictionary<Type, object>();
public static TypeEvent<T> ForType<T>() where T: class, new()
{
Type t = typeof(T);
if (!_typeMap.ContainsKey(t))
{
_typeMap[t] = new TypeEvent<T>();
}
return _typeMap[t] as TypeEvent<T>;
}
public static T InstantiateObject<T>() where T: class, new()
{
T obj = new T();
ForType<T>().RaiseObjectInstantiated(obj);
return obj;
}
}
You could use it like so:
ObjectManager.ForType<Foo>().OnObjectInstantiated += fooInstantiated;
Foo f = ObjectManager.InstantiateObject<Foo>();
Option 2
If you are okay with making ObjectManager itself a static generic class, you could greatly simplify this. Note this means you no longer have just one ObjectManager class - ObjectManager<Foo> and ObjectManager<Bar> are now different classes with different variables. If that's acceptable to you, this makes things a lot cleaner for the small bit you've told us that ObjectManager needs to do:
public static class ObjectManager<T> where T : class, new()
{
// Our event handler will accept a parameter of type T and return void
public static event Action<T> OnObjectInstantiated;
public static T InstantiateObject()
{
T obj = new T();
OnObjectInstantiated?.Invoke(obj);
return obj;
}
}

Calling a parameterless constructor from a parametrized constructor in C#?

I know that we can call a parametered constructor from other constructor using constructor chaining.
But,
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello, world!");
var t1 = new T1("t2");
}
}
public class T1
{
public T1()
{
Console.WriteLine("t1");
}
public T1(string s):base()
{
Console.WriteLine(s);
}
}
this doesn't seem to call the base constructor (without any parameters).
Any ideas ?
EDIT:
Current: t2 is printed. t1 is not on the console.
so, I have resorted to the following method:
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello, world!");
var t1 = new T1("t2");
}
}
public class T1
{
private void privateMethod()
{
Console.WriteLine("common method");
}
public T1()
{
privateMethod();
}
public T1(string s):base()
{
Console.WriteLine(s);
privateMethod();
}
}
Is there any better ways of doing this ?
You are looking for this():
public class T1
{
public T1()
{
Console.WriteLine("t1");
}
public T1(string s) : this()
{
Console.WriteLine(s);
}
}
You're looking for the keyword this, base will call the parent class (as in the class you're extending).
You're actually calling Object() constructor when you use the base keyword. You want to use the this keyword
public class T1
{
public T1()
{
Console.WriteLine("t1");
}
public T1(string s) : this()
{
Console.WriteLine(s);
}
}
As mentioned in other answers, for calling the parameterless constructor you have to use :this() (base() calls the parameterless constructor of the base class)
However, I think this is a bad practice. The constructor with parameters is the one that defines better the initialization of the class, and thus, the parameterless constructor should call it rather than vice versa.
i.e:
public class T1
{
public T1():this(String.Empty) // <= calling constructor with parameter
{
Console.WriteLine("t1");
}
public T1(string s)
{
Console.WriteLine(s);
}
}
rather than:
public class T1
{
public T1()
{
Console.WriteLine("t1");
}
public T1(string s) : this() // <= calling parameterless constructor
{
Console.WriteLine(s);
}
}
BTW, it seems that the language is going towards encouraging using a primary constructor using, well - Primary constructors (it is was an experimental feature in C# 6 that was removed, not sure if for good...)
this called the current class instance while base the parent.

Automatically calling an init function whenever an object is used for the 1st time

I have an object that only initializes itself with barebones data when constructed (fast), and loads itself for real (slow) when first accessed. The idea is that I'm creating a lot of these barebones objects at startup and hash them into a map, then fully load each object whenever it is individually accessed for the first time. The problem is that I cannot guarantee how clients will interact with this object, there are multiple public methods that might be invoked.
Is there a good pattern to support this kind of situation? The obvious (and my current) solution is to track state with an internal bool, check against that bool in every function that might be invoked, and load that way. But that requires code duplication of that behavior across all public functions, and is vulnerable to errors.
I can imagine a single point-of-entry method that then dishes out behaviors based on a client request type etc., but before I go consider going down that road I want to see if there's a commonly accepted approach/pattern that I might not be aware of. I'm doing this in C#, but any insight is appreciated.
If I understood what you want to achieve, you are looking for the Proxy Design Pattern, more specifically, a virtual Proxy.
Refer to http://www.dofactory.com/net/proxy-design-pattern
A small example would be something like:
public abstract class IObjectProvider
{
public abstract IObjectProvider Object{get;}
public abstract void doStuff();
}
public class RealObject : IObjectProvider
{
public RealObject()
{
//Do very complicated and time taking stuff;
}
public override IObjectProvider Object
{
get { return this; }
}
public override void doStuff()
{
//do this stuff that these objects normally do
}
}
public class ObjectProxy : IObjectProvider
{
private IObjectProvider objectInstance = null;
public override IObjectProvider Object
{
get
{
if (objectInstance == null)
objectInstance = new RealObject();
return objectInstance;
}
}
public override void doStuff()
{
if(objectInstance!=null)
objectInstance.doStuff();
}
}
public class SkeletonClass
{
public IObjectProvider Proxy1 = new ObjectProxy();
public IObjectProvider Proxy2 = new ObjectProxy();
}
static void Main(String[] args)
{
//Objects Not Loaded
SkeletonClass skeleton = new SkeletonClass();
//Proxy1 loads object1 on demand
skeleton.Proxy1.Object.doStuff();
//Proxy2 not loaded object2 until someone needs it
}
Here's an example of dynamic proxy approach.
using System;
using System.Diagnostics;
using Castle.DynamicProxy; //Remember to include a reference, too. It's nugettable package is Castle.Core
namespace ConsoleApp
{
public class ActualClass
{
//Have static instances of two below for performance
private static ProxyGenerator pg = new ProxyGenerator();
private static ActualClassInterceptor interceptor = new ActualClassInterceptor();
//This is how we get ActualClass items that are wrapped in the Dynamic Proxy
public static ActualClass getActualClassInstance()
{
ActualClass instance = new ActualClass();
return pg.CreateClassProxyWithTarget<ActualClass>(instance, interceptor);
}
//Tracking whether init has been called
private bool initialized = false;
//Will be used as evidence of true initialization, i.e. no longer null
private int? someValue = null;
public void Initialize()
{
if (!initialized)
{
//do some initialization here.
someValue = -1; //Will only get set to non-null if we've run this line.
initialized = true;
}
}
//Any methods you want to intercept need to be virtual!
public virtual int replaceValue(int value)
{
//below will blow up, if someValue has not been set to -1 via Initialize();
int oldValue = someValue.Value;
someValue = value;
return oldValue;
}
//block off constructor from public to enforce use of getActualClassInstance
protected ActualClass() { }
}
public class ActualClassInterceptor : ActualClass, IInterceptor
{
public void Intercept(IInvocation invocation)
{
//Call initialize before proceeding to call the intercepted method
//Worth noting that this is the only place we actually call Initialize()
((ActualClass)invocation.InvocationTarget).Initialize();
invocation.Proceed();
}
}
class Program
{
static void Main(string[] args)
{
ActualClass instance1 = ActualClass.getActualClassInstance();
ActualClass instance2 = ActualClass.getActualClassInstance();
int x1 = instance1.replaceValue(41);
int x2 = instance2.replaceValue(42);
int y1 = instance1.replaceValue(82);
Debug.Assert(y1 == 41);
int y2 = instance2.replaceValue(84);
Debug.Assert(y2 == 42);
var read = Console.ReadKey();
}
}
}

How to prevent an instantiation of an object in c#

What I need is to check the parameters passed to the constructor and prevent the instantiation of the specific object in case they are treated as invalid.
What I have found is that an exception can be thrown so the object reference will end up with "null" as expected.
For example, this class will be instantiated only if the integer passed to the constructor is non negative.
class MyClass
{
public MyClass(int a)
{
if (a < 0)
{
throw new Exception();
}
}
}
Although the above works fine, I bet that c# can provide a cleaner way to do this, avoiding the extra cost of the try/catch need, each time a new object is about to be constructed.
static void Main(string[] args)
{
MyClass e1;
MyClass e2;
try
{
e1 = new MyClass(1);
}
catch(Exception) { }
try
{
e2 = new MyClass(-1);
}
catch(Exception) { }
}
In cases like this, you should consider using the Factory Pattern. You made the constructor private, and instead use a static method to return an instance.
public class Foo {
private Foo(int a) { ... }
public static Foo GetFoo(int a) {
if (a < 0) {
throw new Exception("No Foo for you!");
// or
return null;
}
return new Foo(a);
}
}
public class Program {
public static void Main() {
Foo f;
f = new Foo(); // Not allowed, ctor is private.
f = Foo.GetFoo(42); // Do this instead.
}
}
With this, you can do some pretty interesting stuff.
Here, we have a Foo class, with different sub-classes. By using the Factory Pattern, we can construct an instance of a particular Foo sub-class, without the outside world even knowing that any subclasses exist!
public abstract class Foo {
// Private implementations of Foo
// No one outside can ever construct one directly.
private class RedFoo : Foo { }
private class GreenFoo : Foo { }
private class BlueFoo : Foo { }
public static Foo GetColoredFoo(string color) {
switch (color.ToLower()) {
case "red": return new RedFoo();
case "green": return new GreenFoo();
case "blue": return new BlueFoo();
}
throw new Exception("No Foo for that color!");
}
}
public class Program {
public static void Main() {
Foo f;
f = new Foo(); // Not allowed; Foo is abstract
f = new RedFoo(); // Not allowed, RedFoo is private, inside of Foo
f = Foo.GetColoredFoo("red"); // Returns an instance of RedFoo
}
}
This moves the knowledge of "how to best construct the object you really need" into the definition of the class itself, and of course eliminates the try/catch. You could apply any logic you need inside of the static factory method.
You can go with the factory pattern, as suggested by MarcinJruaszek, by making the constructor private and add a static method:
public class myClass
{
private myClass(int a)
{
// constructor
}
public static myClass Create(int a){
if (a < 0)
{
return null;
}
return new myClass(a);
}
}
And do myClass.Create(1).
What I suggest you do is create a static method of your class that accepts the parameters you need to verify and have that return the object. I do not know of a way to abandon object creation during a constructor without throwing an Exception.

Categories