Problem when with generic delegates in C# - c#

I have a sample program where I have a class called ObserverTest where I have two methods
one for subscription and one for notify for any type T but I get some build errors.
Following is my sample code>
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ObserverTest obs = ObserverTest.Instance();
obs.SubscribeToChange<int>(GotChange);
obs.NotifyChange<int>(200);
Console.ReadLine();
}
private static void GotChange(int val)
{
Console.WriteLine(string.Format("Changed value is {0}", val));
}
}
public class ObserverTest
{
private static ObserverTest _obsTest;
private Action<T> _observer;
private ObserverTest()
{
}
public static ObserverTest Instance()
{
return _obsTest = _obsTest == null ? new ObserverTest() : _obsTest;
}
public void NotifyChange<T>(T val)
{
_observer(val);
}
public void SubscribeToChange<T>(Action<T> observer)
{
_observer = observer;
}
}
}
and followings are the errors:
Error 1 The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?) C:\Users\Administrator\AppData\Local\Temporary Projects\ConsoleApplication1\Program.cs 24 22 ConsoleApplication1
Error 2 The field 'ConsoleApplication1.ObserverTest._observer' cannot be used with type arguments C:\Users\Administrator\AppData\Local\Temporary Projects\ConsoleApplication1\Program.cs 37 10 ConsoleApplication1
Can anyone please help me in removing the errors ?
Thanks in advance.

Try to add generic in the class definition:
public class ObserverTest<T>
complete code:
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ObserverTest<int> obs = ObserverTest<int>.Instance();
obs.SubscribeToChange<int>(GotChange);
obs.NotifyChange<int>(200);
Console.ReadLine();
}
private static void GotChange(int val)
{
Console.WriteLine(string.Format("Changed value is {0}", val));
}
}
public class ObserverTest<T>
{
private static ObserverTest<T> _obsTest;
private Action<T> _observer;
private ObserverTest()
{
}
public static ObserverTest<T> Instance()
{
return _obsTest = _obsTest == null ? new ObserverTest<T>() : _obsTest;
}
public void NotifyChange<E>(T val)
{
_observer(val);
}
public void SubscribeToChange<E>(Action<T> observer)
{
_observer = observer;
}
}
}

If you have a member that's a generic, like _observer, you need to put a type argument on the ObserverTest class, like so:
public class ObserverTest<T> {
}
Of course, you'll need to modify your Instance method as well.

The problem you are having is that you are declaring a field member that has a generic type and the class does not:
public class ObserverTest
{
private static ObserverTest _obsTest;
private Action<T> _observer;
...
}
So when you try to create an instance of the ObserverTest class, it tries to setup the field members and runs into the problem of not knowing what concrete type _observer is.
To fix this you'll have to define the class with a generic parameter and any calls that instantiate the class:
public class ObserverTest<T>
{
private static ObserverTest _obsTest;
private Action<T> _observer;
public static ObserverTest<T> Instance<T>()
{
...
}
...
}

Related

Why use static methods in program.cs C#? [duplicate]

This question already has answers here:
When to use static methods
(24 answers)
Closed 2 years ago.
I always knew that I have to use static methods but I wonder why?
As you can see below I have to make "MigrateDatabase" Static
using System;
namespace OdeToFood
{
public class Program
{
public static void Main(string[] args)
{
MigrateDatabase();
}
private static void MigrateDatabase()
{
//.....
}
}
}
Let's just be clear, the only reason MigrateDatabase has to be static in this case is because you're calling it from a static method (Main). If instead MigrateDatabase was an instance method on a class, you could instantiate that class and call it
using System;
namespace OdeToFood
{
public class Program
{
public static void Main(string[] args)
{
var migration = new Migration();
migration.MigrateDatabase();
}
}
public class Migration
{
private void MigrateDatabase()
{
//.....
}
}
}
You could also put it as a instance method on Program if you're instantiating an instance of that class
using System;
namespace OdeToFood
{
public class Program
{
public static void Main(string[] args)
{
var program = new Program();
program.MigrateDatabase();
}
private void MigrateDatabase()
{
//.....
}
}
}

How to create a lazy singleton aspect with PostSharp?

Assuming the following singleton declaration for a sealed class with a private constructor:
private static readonly Lazy<MyClass> _singleton = new Lazy<MyClass>(() => new MyClass());
public static MyClass Instance => _singleton.Value;
Is there a way to create a PostSharp aspect that would allow me to add an attribute (PsSingleton) to the Instance property as such:
[PsSingleton]
public static MyClass Instance {get; set;}
and have the class become a lazy singleton at run-time?
using PostSharp.Aspects;
using PostSharp.Reflection;
using PostSharp.Serialization;
using System;
using System.Reflection;
namespace LazySingletonSample
{
class Program
{
static void Main(string[] args)
{
TestClass.Instance.SayHello();
TestClass.Instance.SayHello();
TestClass.Instance.SayHello();
}
}
public class TestClass
{
[LazySingleton]
public static TestClass Instance;
public void SayHello()
{
Console.WriteLine("Hello from singleton!");
}
}
// TODO: Restrict usage
[PSerializable]
public sealed class LazySingletonAttribute : LocationInterceptionAspect
{
object singletonInstance;
ConstructorInfo constructor;
public override bool CompileTimeValidate(LocationInfo locationInfo)
{
// TODO: check that:
// - field name is "Instance"
// - field type is the same as the declaring type
// - there is only a default constructor
// - the constructor is private
// - the constructor is not called anywhere
// - the field is not set anywhere
return true;
}
public override void CompileTimeInitialize(LocationInfo targetLocation, AspectInfo aspectInfo)
{
this.constructor = targetLocation.DeclaringType.GetConstructor(new Type[] { });
}
public override void OnGetValue(LocationInterceptionArgs args)
{
if (this.singletonInstance == null)
{
Console.WriteLine("Creating singleton instance.");
this.singletonInstance = constructor.Invoke(new object[] { });
}
Console.WriteLine("Returning singleton instance.");
args.Value = this.singletonInstance;
}
public override void OnSetValue(LocationInterceptionArgs args)
{
throw new InvalidOperationException();
}
}
}

Derived types with Method overloading

The code is simple enough to understand I hope.
I'm trying to use an interface type IColor in order to pass color objects to the ColorManager. I then want the ColorManager to pass this object to the IColor object as its own type, so the method overloads gets called.
However, it seems since it is being passed as the IColor type, C# will not implicity cast it into its complete type as either a BlueColor or GreenColor.
I hope this makes some sense to somebody on what I want to achieve. Is this possible in C#?
[Solution]
http://msdn.microsoft.com/en-us/library/dd264736.aspx
Overload Resolution with Arguments of Type dynamic
My code so far:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
namespace Example
{
public interface IColor
{
void CatchColor(IColor c);
}
public class BlueColor : IColor
{
public void CatchColor(IColor c)
{
}
}
public class GreenColor : IColor
{
public void CatchColor(BlueColor c)
{
Console.WriteLine("CAUGHT BLUE!");
}
public void CatchColor(GreenColor c)
{
Console.WriteLine("CAUGHT GREEN!");
}
public void CatchColor(IColor c)
{
Console.WriteLine("CAUGHT SOME COLOR!");
}
}
public class ColorManager
{
public void PassColor(IColor c)
{
// Don't use static type-checking
// Problem solved
dynamic AnyColor = c;
AnyColor.CatchColor(AnyColor);
}
public static void Main()
{
GreenColor G = new GreenColor();
new ColorManager().PassColor(G);
Console.ReadLine();
return;
}
}
}
One possiblity to tell the ColorManager class to use the correct type of the passed object is to use an abstract class, that already implements the CatchColor:
public abstract class IColor
{
// override in every class
public abstract void PrintColor();
// has the correct type passed with the interface
public void CatchColor(IColor c)
{
c.PrintColor();
}
}
Then the sub classes need to implement only PrintColor with the correct color:
public class BlueColor : IColor
{
public override void PrintColor()
{
Console.WriteLine("BLUE!");
}
}
public class GreenColor : IColor
{
public override void PrintColor()
{
Console.WriteLine("GREEN!");
}
}
The manager is the same:
public class ColorManager
{
public void PassColor(IColor c)
{
c.CatchColor(c);
}
}
It can be used like this:
GreenColor G = new GreenColor();
var cm = new ColorManager();
cm.PassColor(G);
cm.PassColor(new BlueColor());
The outputs is:
GREEN!
BLUE!
What you want is late method binding.
The downside to this is you have to add methods for each new type of color. The upside is you don't have to maintain a case statement or conditional logic.
See here for more detail:
Early and late binding
Edit: Here is a working example of this type of late-binding.
class Program {
static void Main(string[] args) {
//Declare instances
BaseClass myClass = new Class2();
BaseClass otherClass = new Class1();
//Invoke the action method which will match based on the BaseClass type
Action(myClass);
Action(otherClass);
Console.ReadLine();
}
public static void Action(BaseClass classType) {
//Remove the compile-time type so the runtime can select the method based on signature
dynamic aClass = classType;
ServiceMethod(aClass);
}
public static void ServiceMethod(dynamic input) {
Methods(input);
}
public static void Methods(Class1 classType) {
Console.WriteLine("Class1");
Debug.WriteLine("Class1");
}
public static void Methods(Class2 classtype) {
Console.WriteLine("Class2");
Debug.WriteLine("Class2");
}
public static void Methods(Class3 classType) {
Console.WriteLine("Class3");
Debug.WriteLine("Class3");
}
}
public abstract class BaseClass { //This could also be an interface
public Guid Id { get; set; }
public string Name { get; set; }
}
public class Class1 : BaseClass {
}
public class Class2 : BaseClass{
}
public class Class3 : BaseClass {
}
So you want something like:
public void CatchColor(Color c)
{
if (c is BlueColor)
CatchColor(c as BlueColor);
if (c is GreenColor)
CatchColor(c as GreenColor);
}
?

How to create an Extension Method that accepts a class and an interface as a parameters

For example I am trying to achieve this:
class A
{
}
class B
{
}
interface C
{
void SomeMethod();
}
A.ExtentionMethod(B,C);
Notice that I am passing the Type A and C to ExtentionMethod (Not an instance)
Another option would be to use generics instead of passing parameters
public static class Extensions
{
public static void ExtensionMethod<T1, T2>(this A a)
{
// ANywhere you would use the parameters use T1 and T2 instead.
}
}
A a;
a.ExtensionMethod<B, C>();
IMO, this is more readable than when using typeof().
Use this code:
public static class Util
{
public static void ExtensionMethod<t1, t2>(this A aobj)
{
}
}
public static class Extensions
{
public static void ExtensionMethod(this A a, Type c1, Type c2)
{
}
}
A a;
a.ExtensionMethod(typeof(B), typeof(C));
However, I don't see how this is very useful. Please be a bit more specific on what you want.
you can use the interface like this
public static class Extension
{
public static void Method1(this IMyInterface myInterface, int i)
{
Console.WriteLine("Extension.Method1");
}
public static void Method1(this IMyInterface myInterface, string s)
{
Console.WriteLine("Extension.Method1");
}
}

Alias for static member in C#?

I have a static member:
namespace MyLibrary
{
public static class MyClass
{
public static string MyMember;
}
}
which I want to access like this:
using MyLibrary;
namespace MyApp
{
class Program
{
static void Main(string[] args)
{
MyMember = "Some value.";
}
}
}
How do make MyMember accessible (without MyClass.) to MyApp just by adding using MyLibrary?
C# doesn't allow you to create aliases of members, only of types. So the only way to do something like that in C# would be to create a new property which is accessible from that scope:
class Program
{
static string MyMember
{
get { return MyClass.MyMember; }
set { MyClass.MyMember = value; }
}
static void Main(string[] args)
{
MyMember = "Some value.";
}
}
It's not really an alias, but it accomplishes the syntax you're looking for.
Of course, if you're only accessing / modifying a member on MyClass, and not assigning to it, this can be simplified a bit:
class Program
{
static List<string> MyList = MyClass.MyList;
static void Main(string[] args)
{
MyList.Add("Some value.");
}
}

Categories

Resources