question about reflection, attributes in c# - c#

I have such work to(lab) do:
... information about events must e written in some files, which must be determinated by attached to this class attribute.
Wgat a sense is in this attribute? what it must to do?
All lab is "Write generic class of list with opportunity to generate events when you call some class methods. Information about events must e written in some files, which must be determinated by attached to this class attribute.
I don't understand reason of using in this lab attribute, please help me.
Here I have written sample generic class of list
Here are two files:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Lab7
{
public class MyListClass<T>: IEnumerable<T>
{
public delegate void MyDelegate();
public event MyDelegate AddEvent;
public event MyDelegate RemEvent;
List<T> list;
public T this[int index]
{
get { return list[index]; }
set { list[index] = value; }
}
public void Add(T item)
{
list.Add(item);
if (AddEvent != null)
AddEvent();
}
public void Remove(T item)
{
list.Remove(item);
if (RemEvent != null)
RemEvent();
}
public void RemoveAt(int index)
{
list.RemoveAt(index);
if (RemEvent != null)
RemEvent();
}
public MyListClass()
{
list = new List<T>();
}
public MyListClass(List<T> list)
{
this.list = list;
}
public IEnumerator<T> GetEnumerator()
{
return list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return list.GetEnumerator();
}
#region Events
/*static void AddHandler()
{
Console.WriteLine("Объект добавлен в коллекцию");
}
static void RemoveHandler()
{
Console.WriteLine("Объект удалён из коллекции");
}*/
#endregion
}
}
and here is main class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Lab7
{
class Program
{
static void Main(string[] args)
{
MyListClass<int> lst = new MyListClass<int>();
lst.AddEvent +=new MyListClass<int>.MyDelegate(AddHandler);
lst.RemEvent+=new MyListClass<int>.MyDelegate(RemoveHandler);
lst.Add(2542);
lst.Add(785);
lst.RemoveAt(1);
}
static void AddHandler()
{
Console.WriteLine("Объект добавлен в коллекцию");
}
static void RemoveHandler()
{
Console.WriteLine("Объект удалён из коллекции коллекцию");
}
}
}
Sorry for my bad English. I don't say to do all lab for me, only give me ideas, and examples how to write this)

The question is difficult to understand, but I think it wants you do decorate your class or methods with an attribute which points to a file in which some sort of event data is stored.
So it would look something like this:
class SomeClass
{
[MyEventInfoAttribute(EventFile = "c:\\blah\\events.foo")]
void SomeMethod()
{
}
}
So you need to define an attribute:
public class MyEventInfoAttribute : Attribute
{
public property string EventFile { get; set; }
}
How you store the event information and implement the events is up to you.
Your code would have to use reflection to discover the attribute on the methods.
For example:
class SomeClass
{
[MyEventInfoAttribute(EventFile = "c:\\blah\\events.foo")]
void SomeMethod()
{
Type type = typeof(SomeClass);
MethodInfo method = type.GetMethod("SomeMethod");
object[] atts = method.GetCustomAttributes();
if (atts.Length > 0)
{
if (atts[0] is MyEventInfoAttribute)
{
string fileName = ((MyEventInfoAttribute)atts[0]).EventFile;
... now open the file, read the event info, and use it ...
}
}
}
}
This is a simplified example to give you an idea of the direction to go in.

Related

Stack implementation by list code review, is my solution correct?

I've had homework to do for my programming lectures, and I don't know that is my solution correct?
I've had to implement stack by the list, but I don't know am I understood it correctly.
Sorry for my English :)
using System;
using System.Collections.Generic;
using System.Text;
namespace Zad._20
{
class Element
{
public String value;
public Element previous;
public Element(String value) {
this.value = value;
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace Zad._20
{
class Stack
{
private Element top;
public Stack() {
top = null;
}
public void Push(Element e) {
e.previous = top;
top = e;
}
public void Pop() {
top = top.previous;
}
public void Print() {
while(top != null) {
Console.WriteLine(top.value);
top = top.previous;
}
}
}
}
It seems, that you are trying to implement Stack<T> via LinkedList (well known classical problem), not List; if you insist on List<T>
the code will be quite simple. Your code rewritten to List<T>:
// <T> - let's have a generic stack, e.g. MyStack<int> or MyStack<String>
public class MyStack<T> {
// List<T> in which we store the stack's items
private List<T> m_Items = new List<T>();
// Nothing to write home about; we can safely drop this constructor
public MyStack() {}
public void Push(T item) {
// Just add item to the items
m_Items.Add(item);
}
public T Pop() {
// We can't Pop an item from the empty stack
if (m_Items.Count <= 0)
throw new InvalidOperationException("Stack is empty");
else {
// Take the last item
T result = m_Items[m_Items.Count - 1];
// Remove it (the last item) from the list
m_Items.RemoveAt(m_Items.Count - 1);
// Return the last item
return result;
}
}
public void Print() {
// Print out all the items in reversed order
for (int i = m_Items.Count - 1; i >= 0; --i)
Console.WriteLine(m_Items[i]);
}
}

Accessing methods of a child object, through a Dictionary

New programmer, using C# and VB 2015, first time post so please be gentle!
Basically I am using Dictionary for the first time, and I am trying to access the method useMedPack() which inside my MedPack class, which is a child of Item, which is being created when adding it to my Dictionary. The problem is that it says:
****EDIT**** I feel like I should have added the Item class in first time round (now added to the bottom). Following some awesome suggestions, I casted using ((MedPack)inventory["MedPack"]).useMedPack(); and it now works as intended! Although some of the feedback has been great and I have learned a lot from everyones suggestions! :)
'Item' does not contain a definition for useMedPack();.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Dictionary<String, Item> inventory = new Dictionary<String, Item>();
inventory.Add("MedPack", new MedPack("MedPack", 1));
MedPack.pickUpMedPack(inventory);
//THIS IS THE PROBLEM inventory["MedPack"].useMedPack();
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
}
namespace ConsoleApplication1
{
class MedPack : Item
{
private int healthReturn = 10;
public MedPack() : base()
{
}
public MedPack(String itemName, int itemQuantity) : base(itemName, itemQuantity)
{
}
public void useMedPack()
{
decreaseQuantity(1);
}
public static void pickUpMedPack(Dictionary<String, Item> inventory)
{
if (!inventory.ContainsKey("MedPack"))
{
inventory.Add("MedPack", new MedPack("MedPack", 1));
Console.WriteLine("You found a MedPack! It was added to the inventory");
}
else
{
inventory["MedPack"].increaseQuantity(1);
Console.WriteLine("You found ANOTHER MedPack! It was added to the inventory");
}
}
}
}
namespace ConsoleApplication1
{
class Item
{
private String itemName;
private int itemQuantity;
public Item(String itemName, int itemQuantity)
{
this.itemName = itemName;
this.itemQuantity = itemQuantity;
}
public Item()
{
}
public void increaseQuantity(int increaseQuantity)
{
this.itemQuantity += increaseQuantity;
}
public void decreaseQuantity(int increaseQuantity)
{
this.itemQuantity -= increaseQuantity;
}
public String getName()
{
return this.itemName;
}
public void setName(String name)
{
this.itemName = name;
}
public int getQuantity()
{
return this.itemQuantity;
}
public void setQuantity(int x)
{
this.itemQuantity = x;
}
}
}
Your dictionary stores objects of type Item. There's no guarantee that an arbitrary Item will be a MedPack therefore you can't directly call useMedPack on it.
If, in your case, you know that the item is a MedPack you can just cast it:
((MedPack)inventory["MedPack"]).useMedPack();
or in two lines:
MedPack mp = (MedPack)inventory["MedPack"];
mp.useMedPack();
If, at run time, the item is not a MedPack, you'll get an exception.
If you want a single method that can be applied to all item types ,then define it in Item and override it in the sub-classes as necessary:
in Item:
public virtual void UseItem()
{
// base implementtaion
}
in MedPack:
public override void UseItem()
{
// implementation specific to MedPack
}

Static method of class A is not called from the static constructor of class B

I have the following classes
public class A
{
protected static Dictionary<string,Func<BaseClass>> dict = new Dictionary<string,Func<BaseClass>>();
public static void AddGenerator(string type,Func<BaseClass> fncCreateObject)
{
dict.Add(type,fncCreateObject);
}
}
class B : BaseClass
{
static B()
{
A.AddGenerator("b",CreateObject);
}
protected B()
{}
pulic static B CreateObject()
{
return new B();
}
}
NOTE: The above code is simply an example but very closely relates to the what I'm trying to achieve.
Many people would advice using an IoC container such as NInject or Unity but my main reason for this post if to figure out why the above code does not execute as it is expected to.
So, in the above code, I'm expecting class B's static constructor to call on the static method of class A and an entry should be available in the dictionary for the rest of the application life cycle.
However, when I run the code and debug, I found that the dictionary is empty.
Why is the code invoked from class B's static constructor not executing?
From the documentation:
A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.
Clearly, at the point in your code where you inspect the dictionary, no instance has yet been created, and no static members have been referenced.
Not exactly a 1:1 translation, of your sample into MEF, but it should give you a good idea what MEF is capable of:
using System;
using System.Collections.Generic;
namespace ConsoleApplication4
{
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var directoryCatalog = new DirectoryCatalog(".");
var compositeCatalog = new AggregateCatalog(assemblyCatalog, directoryCatalog);
var container = new CompositionContainer(compositeCatalog);
var a = A.Instance;
container.SatisfyImportsOnce(a);
a.PrintCatalog();
}
}
public sealed class A
{
private static readonly A instance = new A();
static A() { }
private A() { }
public static A Instance { get { return instance; } }
[ImportMany]
private List<IBType> BTypes;
public void PrintCatalog()
{
foreach (var bType in BTypes)
{
Console.WriteLine(bType.GetType());
}
}
}
[Export(typeof(IBType))]
class B:IBType
{
static B()
{
}
protected B()
{}
public void DoSomething() { }
}
[Export(typeof(IBType))]
class B2:IBType
{
static B2()
{
}
protected B2()
{}
public void DoSomething() { }
}
interface IBType
{
void DoSomething();
}
}
I've also included the safest implementation of a Singleton pattern known to me. MEF will allow you to source many implementations of the same interface which are resolved dynamically at runtime. I used it also with metadata attributes, like version and name.
But if you need it to work with a base abstract class, check out this article.
The same code as above, but with metadata attributes use sample:
using System;
using System.Collections.Generic;
namespace ConsoleApplication4
{
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var directoryCatalog = new DirectoryCatalog(".");
var compositeCatalog = new AggregateCatalog(assemblyCatalog, directoryCatalog);
var container = new CompositionContainer(compositeCatalog);
var a = A.Instance;
container.SatisfyImportsOnce(a);
a.PrintCatalog();
a.BTypes.Single(s=>s.Metadata.Name.Equals("Second")).Value.DoSomething();
}
}
public sealed class A
{
private static readonly A instance = new A();
static A() { }
private A() { }
public static A Instance { get { return instance; } }
[ImportMany]
public List<Lazy<IBType,IBTypeMetadata>> BTypes;
public void PrintCatalog()
{
foreach (var bType in BTypes)
{
Console.WriteLine(bType.Value.GetType());
}
}
}
[Export(typeof(IBType))]
[BTypeMetadata("First")]
class B:IBType
{
static B()
{
}
protected B()
{}
public void DoSomething() { }
}
[Export(typeof(IBType))]
[BTypeMetadata("Second")]
class B2 : IBType
{
static B2()
{
}
protected B2()
{}
public void DoSomething()
{
Console.WriteLine("Hello from Second");
}
}
public interface IBType
{
void DoSomething();
}
public interface IBTypeMetadata
{
string Name { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class BTypeMetadataAttribute : ExportAttribute
{
public string Name { get; set; }
public BTypeMetadataAttribute(string name)
: base(typeof(IBTypeMetadata)) { Name = name; }
}
}
IMHO, MEF might help you as long as your plan is to call some public methods from a particular instance of any of the B-types. In your sample, you simply create new instances of a B-type, and I think there is more to it than what your sample shows.
MEF will create catalogs for you from your currently loaded assembly, as well as any number of assemblies from any number of directories. You can even have it dynamically re-composable, meaning, at runtime, you could potentially retrieve a DLL from a server, and have it added to your catalog without shutting down the application.
MEF is also hierarchical, so your B-types can have their own "catalogs". And to wire it all up, all you have to do is to call SatifyImportsOnce passing an instance of class A.

Testing using RHinomock

I have a class to test which is tricky to test using Rhinomock unlike normal classes bacause its constructor is injected with a dependency which is not a single interface but an array of Interface objects. Please help me set up all stuff to write a test using rhinomock.
namespace ClinicalAdvantage.Domain.UserAppSettings
{
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
public class Agg : IAgg
{
private readonly ISource[] sources;
public Agg(ISource[] sources)
{
this.sources = sources;
}
public JObject GetAll()
{
var obj = new JObject();
foreach (var source in this.sources)
{
var token = source.GetCurr();
if (token != null)
{
obj.Add(new JProperty(source.Name, token));
}
}
return obj;
}
}
ISource is an interface which has 2 implementations. GetALL() iterates thro each implementated class object and calls the GetCurr method in each of the object and aggregates the result. I have to stub GetCurr method to return a standard Jtoken. I am unable to create a mock of this class Agg or a stub of ISource.
public interface ISource
{
string Name { get; }
bool Enabled { get; }
JToken GetCurr();
}
}
Something like this might work:
[TestClass]
public class AggTest
{
private ISource Isource;
private Agg agg;
[TestInitialize]
public void SetUp()
{
Isource = MockRepository.GenerateMock<ISource>();
agg = new Agg(new [Isource]);
}
[TestMethod]
public void GetAll()
{
Isource.Stub(x => x.GetCurr()).
Return(new JToken());
var jObject = agg.GetAll();
Assert.IsNotNull(jObject);
// Do your assertion that all JProperty objects are in the jObject
// I don't know the syntax
}
}

Implementing IEnumerable. Error.

my Code is :
using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
namespace IEnumerable
{
public class MyEnumerable<T> : IEnumerable<T>
{
public MyEnumerable(T[] items)
{
this.items = items;
}
public IEnumerator<T> GetEnumerator()
{
return new NestedEnumerator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
// The enumerator definition.
class NestedEnumerator : IEnumerator<T>
{
public NestedEnumerator(MyEnumerable<T> coll)
{
Monitor.Enter(coll.items.SyncRoot);
this.index = -1;
this.coll = coll;
}
public T Current
{
get { return current; }
}
object IEnumerator.Current
{
get { return Current; }
}
public bool MoveNext()
{
if (++index >= coll.items.Length)
{
return false;
}
else
{
current = coll.items[index];
return true;
}
}
public void Reset()
{
current = default(T);
index = 0;
}
public void Dispose()
{
try
{
current = default(T);
index = coll.items.Length;
}
finally
{
Monitor.Exit(coll.items.SyncRoot);
}
}
private MyEnumerable<T> coll;
private T current;
private int index;
}
private T[] items;
}
public class EntryPoint
{
static void Main()
{
MyEnumerable<int> integers = new MyEnumerable<int>(new int[] { 1, 2, 3, 4 });
foreach (int n in integers)
{
Console.WriteLine(n);
}
}
}
}
I am implementing this piece of code But i get an error. Can anybody help me what to do to error free this code? please help.
My Errors are :
1->'IEnumerable' is a 'namespace' but is used like a 'type'
2->'IEnumerable.MyEnumerable' does not implement interface member 'System.Collections.IEnumerable.GetEnumerator()'. 'IEnumerable.MyEnumerable.GetEnumerator()' cannot implement 'System.Collections.IEnumerable.GetEnumerator()' because it does not have the matching return type of 'System.Collections.IEnumerator'.
The error is likely that you're using IEnumerable as your namespace when it's already a type in the system.
This means that your references to IEnumerable are refering to the current namespace and not the IEnumerable you're meaning to use (System.Collections.IEnumerable).
Try changing your namespace to something else.
Listen to what the compiler is telling you and change your namespace to something sensible (like BlingBlingWoo)
...
using System.Collections.Generic;
namespace BlingBlingWoo
{
public class MyEnumerable<T> : IEnumerable<T>
...
Whats happening here is:
Error : 'IEnumerable' is a 'namespace' but is used like a 'type'
You are trying to use the type IEnumerable, but you've created a namespace called IEnumerable and so the compiler things its a namespace.

Categories