Lets say i have the following attribute class.
//Attribute Implementation
public abstract class TestAttribute : Attribute
{
public abstract void UpdateSomething(string s);
}
public class CustomAttTest : TestAttribute
{
private State state;
public CustomAttTest(State state)
{
this.state = state;
}
public override void UpdateSomething(string s)
{
if (state.Equals(State.First))
{
Console.WriteLine("First State!! " + s);
}
}
}
public enum State
{
First, Second, Third
}
How can i call the Updatesomthing function inside the attribute class?
following is the attribute implementation example.
public abstract class Vehicle
{
//Coode
}
[CustomAttTest(State.First)]
public class Ferrari : Vehicle
{
//Code
}
Here is the full code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
var foo = new Ferrari();
//How do i call the UpdateSomething implemented insde the CustomAttTest attribute class?
}
}
public abstract class Vehicle
{
//Coode
}
[CustomAttTest(State.First)]
public class Ferrari : Vehicle
{
//Code
}
//Attribute Implementation
public abstract class TestAttribute : Attribute
{
public abstract void UpdateSomething(string s);
}
public class CustomAttTest : TestAttribute
{
private State state;
public CustomAttTest(State state)
{
this.state = state;
}
public override void UpdateSomething(string s)
{
if (state.Equals(State.First))
{
Console.WriteLine("First State!! " + s);
}
}
}
public enum State
{
First, Second, Third
}
}
You need to use reflection:
foo.GetType().GetCustomAttribute<CustomAttTest>().UpdateSomething(...);
However, you should probably use an abstract method or property instead of an attribute.
Related
first, sorry for my bad English. I'm learning some design patterns. I try to implement a factory in an example-code. This is the Code.
Program.cs:
namespace Factorymethod_self
{
internal class Program
{
static void Main(string[] args)
{
Animal myDog = new Dogs().SummonAnimal();
myDog.Name = "Rex";
myDog.Run(); // Isn't working
myDog.Bark(); // Isn't working
myDog.Pet(); // Isn't working
}
}
}
Animal.cs:
namespace Factorymethod_self
{
public class Animal
{
private string name;
public string Name
{
get => name;
set => name = value;
}
}
}
Mammal.cs:
using System;
namespace Factorymethod_self
{
public class Mammal : Animal
{
public void Run() => Console.WriteLine(Name + " is running");
}
}
Bird.cs:
using System;
namespace Factorymethod_self
{
public class Bird : Animal
{
public void Fly() => Console.WriteLine(Name + " is flying");
}
}
GeneralFactory.cs:
using System;
namespace Factorymethod_self
{
public abstract class GeneralFactory
{
public abstract Animal SummonAnimal();
public void Pet()
{
Console.WriteLine("You petted " + SummonAnimal().Name);
}
}
}
Dogs.cs:
using System;
namespace Factorymethod_self
{
internal class Dogs : GeneralFactory
{
public void Bark() => Console.WriteLine("The Dog is barking");
public override Animal SummonAnimal()
{
Animal animal = new Mammal();
return animal;
}
}
}
I think, the method Bark() isn‘t accessible, because Animal myDog = new Dogs().SummonAnimal(); doesn’t impellent the class Dogs() but Mammal(). But I Doesn’t understand, why the methods Run() and Pet() aren’t accessible.
If I use GeneralFactory myDog = new Dogs();, I can access the Method Pet() but I don’t think, this is how the Factory should work.
I’ve added a map for the classes
So, there are my questions.
What am I doing wrong here?
How can I try to solve it?
Is this even a right factory?
Thank you very much.
Whenever the TestAttribute attribute is called on a class, I would like to add that type to a list. How can I do that?
Example:
using System;
using System.Collections.Generic;
[AttributeUsage(AttributeTargets.Class)]
public class TestAttribute : Attribute {
public TestAttribute() {
// Add type to list
}
}
public static class TypeHolder {
public static List<Type> Types = new List<Type>();
}
[Test]
public static class MainClass {
public static void Main(string[] args) {
Console.WriteLine(TypeHolder.Types.Count);
}
}
I have a base class implementing an interface and further a specialized class inheriting the base class.
I have implemented interface's method in base class and marked it as virtual, also overridden the same method in specialized class.
Now i want to resolve the method GetData() on some basis that it either returns base class's method or child class's method.
So basically how can I call base class method using the specialized class's reference or interface's reference?
Edit 1
I have an existing data provider and I want to keep its functionality as it is and want to use some subclass or wrapper class where i can write a new implementation(another provider), mind that I want to keep running existing provider as it is for existing scenario and the new provider for other scenarios). what if i use decorator pattern to solve this? Any other pattern which can solve this ?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
interface IDataProvider
{
void GetData();
}
abstract class StandardDataProvider : IDataProvider
{
public virtual void GetData()
{
Console.WriteLine("GetData_StandardDataProvider");
}
}
class ManagedDataProvider : StandardDataProvider
{
public override void GetData()
{
Console.WriteLine("GetData_ManagedDataProvider");
}
}
class Program
{
static void Main(string[] args)
{
IDataProvider dataprovider = new ManagedDataProvider();
dataprovider.GetData();
Console.ReadLine();
}
}
}
This is the only solution I could come up with for your problem:
interface IDataProvider
{
void GetData();
}
abstract class StandardDataProvider : IDataProvider
{
public virtual void GetData()
{
Console.WriteLine("GetData_StandardDataProvider");
}
}
class ManagedDataProvider : StandardDataProvider
{
public override void GetData()
{
Console.WriteLine("GetData_ManagedDataProvider");
}
public void GetBaseData()
{
base.GetData();
}
}
class Program
{
static void Main(string[] args)
{
IDataProvider dataprovider = new ManagedDataProvider();
dataprovider.GetData();
if (dataprovider is ManagedDataProvider)
{
(dataprovider as ManagedDataProvider).GetBaseData();
}
Console.ReadLine();
}
}
Another Way to attack it is adding GetBaseData to the Interface.
interface IDataProvider
{
void GetData();
void GetBaseData();
}
abstract class StandardDataProvider : IDataProvider
{
public virtual void GetData()
{
Console.WriteLine("GetData_StandardDataProvider");
}
public virtual void GetBaseData()
{
Console.WriteLine("GetData_StandardDataProvider");
}
}
class ManagedDataProvider : StandardDataProvider
{
public override void GetData()
{
Console.WriteLine("GetData_ManagedDataProvider");
}
public override void GetBaseData()
{
base.GetData();
}
}
class Program
{
static void Main(string[] args)
{
IDataProvider dataprovider = new ManagedDataProvider();
dataprovider.GetData();
dataprovider.GetBaseData();
Console.ReadLine();
}
}
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);
}
?
I have an abstract base class called Rack and I have different types of racks that are the children of Rack. I want to be able to dynamically cast the generic C# object to different children of the Rack class in order to call the correct getData method in which all children have as a method. Here is what I have so far.
The code below calls the virtual method in the Rack base class. I need it to call the methods within the child classes of Rack.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace IO_Interface
{
class Channel
{
private object rack1;
private object rack2;
public Channel()
{
}
public Channel(object h1, object h2)
{
rack1 = h1;
rack2 = h2;
}
public void send()
{
Type rack1Info = rack1.GetType();
Type rack2Info = rack2.GetType();
string name = rack1.ToString();
MethodInfo castMethod = rack1.GetType().GetMethod("getData").;
castMethod.Invoke(rack1.GetType(), null);
}
}
}`
What you want to do is declare your rack1 and rack2 as Racks, which will be an abstract class with an abstract method GetData. You will instantiate them as child classes of Rack somewhere. Then, when you make a call to GetData on a Rack, it will find the overridden method and call it. Here's an example.
abstract class Rack
{
public abstract void GetData();
}
class ChildRack1 : Rack
{
public override void GetData(){}
}
class ChildRack2 : Rack
{
public override void GetData(){}
}
class Channel
{
private Rack rack1;
private Rack rack2;
public Channel()
{
}
public Channel(Rack h1, Rack h2)
{
rack1 = h1;
rack2 = h2;
}
public void send()
{
rack1.GetData();
}
}
I think this will provide you with the implementation you want:
class Channel
{
private List<Rack> racks;
public Channel()
{
racks = new List<Rack>();
}
public Channel(params Rack[] racks)
{
this.racks = racks.ToList();
}
public void send()
{
foreach (Rack item in racks)
{
item.getData();
}
}
public void SendSpecificRack(Rack rack)
{
//calls the getdata of the rack object passed
rack.getData();
}
}
public class Rack
{
public virtual void getData()
{
Console.WriteLine("Base Rack");
}
}
public class RackChild1 : Rack
{
public override void getData()
{
Console.WriteLine("RackChild1");
}
}
public class RackChild2 : Rack
{
public override void getData()
{
Console.WriteLine("RackChild2");
}
}
Usage:
Channel chn = new Channel(new Rack[]{new RackChild1(),new RackChild2()});
chn.send();
RackChild2 rck = new RackChild2();
chn.SendSpecificRack(rck);
Output:
RackChild1
RackChild2
RackChild2