public class StepClause
{
public NamedStepClause Action1() {}
public NamedStepClause Action2() {}
}
public class NamedStepClause : StepClause
{
public StepClause Step(string name) {}
}
Basically, I want to be able to do something like this:
var workflow = new Workflow().Configure()
.Action1()
.Step("abc").Action2()
.Action2()
.Step("def").Action1();
So, some "steps" are named and some are not.
The thing I do not like is that the StepClause has knowledge of its derived class NamedStepClause.
I tried a couple of things to make this sit better with me.
I tried to move things out to interfaces but then the problem just moved from the concrete to the interfaces - INamedStepClause still need to derive from IStepClause and IStepClause needs to return INamedStepClause to be able to call Step().
I could also make Step() part of a completely separate type. Then we do not have this problem and we'd have:
var workflow = new Workflow().Configure()
.Step().Action1()
.Step("abc").Action2()
.Step().Action2()
.Step("def").Action1();
Which is ok but I'd like to make the step-naming optional if possible.
I found this other post on SO here which looks interesting and promising.
What are your opinions? I'd think the original solution is completely unacceptable or is it?
By the way, those action methods will take predicates and functors and I don't think I want to take an additional parameter for naming the step there.
The point of it all is, for me, is to only define these action methods in one place and one place only. So the solutions from the referenced link using generics and extension methods seem to be the best approaches so far.
I'll give you two options.
Option A
var a = new A.NamedStepClause();
a.Action1()
.Step("abc").Action2()
.Action2()
.Step("def").Action1();
namespace A
{
public class StepClause<SC> where SC : StepClause<SC>
{
public SC Action1() { return null; }
public SC Action2() { return null; }
}
public class NamedStepClause : StepClause<NamedStepClause>
{
public NamedStepClause Step(string name) { return null; }
}
}
Option B
var b = new B.StepClause();
b.Action1()
.Step("abc").Action2()
.Action2()
.Step("def").Action1();
namespace B
{
public class StepClause
{
public StepClause Action1() { return null; }
public StepClause Action2() { return null; }
}
public static class StepClauseExtensions
{
public static StepClause Step(this StepClause #this, string name)
{ return null; }
}
}
Both options compile and give you the fluent interface that you're looking for. I'm more inclined to go with option A as it gives you access to the inner workings of the class. Using extension methods means you may need to give some sort of external access to your class thus breaking encapsulation.
Good luck!
Related
Thanks ahead, community!
As the title describes, I would like to cast an object that is in parent type to a child type, which is actually a child type, whilst this 'specific type' cannot be known until runtime.
Lets say I have following data holder:
public class Holder {}
public class Holder<T> : Holder
{
public T Value;
}
And this Holder (not Holder<T>) will be given to some script at runtime.
I need to cast this Holder into Holder<T> (eg, Holder<string>), so that I can access the Value : T.
For now, I can just mannually add casting cases and their coresponding methods to process it, but time by time there will be more types that goes into this Holder<T>, and it would become imposible to manage in this way.
Is there a way to accomplish this objective?
This Holder must not be flattened, as it is being used in a context as below:
public class SomeNode
{
protected Holder holder;
}
public class SomeNode<T> : SomeNode
{
public SomeNode<T>()
{
holder = new Holder<T>();
}
}
I have no clue how to approach this, nor a search keyword to catch a hint about this.
Automatic suggestions came up before posting seems not my case, which were:
C# Create (or cast) objects of a specific type at runtime
C# Accessing generic Method without knowing specific type
Edit
Thanks to #W.F., I could start searching with an effective keyword 'dynamic object', and I ended up finding System.Reflection as my desired soultion.
It looks like as belows and currently it solves my immediate issue:
holder.GetType().GetProperty("GetValue").Invoke(holder, null);
But as pointed out by #OlivierJacot-Descombes, my structure and a way of using it is breaking a purpose of polymorphism. Therefore I still need a better solution, which would do a job I am looking for and also not breaking polymorphism.
Possible walkaround that comes in my head is that, first, create a method GetValue() in Holder, and also create class that inherits from Holder to implement this method:
public class Holder
{
public virtual string GetValue() => "";
}
public class Holder<T> : Holder
{
public T Value;
}
public class FloatHolder : Holder<float> //for example
{
public override string GetValue() => Value.ToString();
}
Second, change node structure like:
public class SomeNode
{
protected Holder holder;
}
public class SomeNode<T> : SomeNode {}
public class FloatNode : SomeNode<float>
{
public FloatNode()
{
holder = new FloatHolder();
}
}
Then, I can do like:
public class EchoNode : SomeNode
{
public void Tick()
{
Console.WriteLine(holder.GetValue());
}
}
Seems like too many classes are being created, but it also seems not breaking polymorphism.
Looking for further advices. Again, Thanks!
Edit#2
I already said this in the comment, but for better readability, I write this here as well.
Both Dynamic Object and System.Reflection were easy and fitting solutions which I was looking for, but they weren't best solutions in general.
At the beginning I was misinterpreting #OlivierJacot-Descombes 's answer. He was overall pointing out two impediments: first, my class structure is breaking polymorphism, and second, reflection is slow (and later I noticed, dynamic object as well). I didn't catch the last bit at first so I went through a long way.
Moreover, turned out, I couldn't use dynamic object for my project context, as I am not using normal C# but a Unity C#. Technically I can, but they don't blend well.
Thankfully, my revised solution was acceptable. Therefore I decided to select #OlivierJacot-Descombes 's post as an answer. But I hope, still, people would approach and leave me an good advices.
Thank you all.
If you need to cast to a specific type, you are doing polymorphism wrong. Of course you could do something like this:
switch (holder)
{
case Holder<string> stringHolder:
DoStringThing(stringHolder.Value);
break;
case Holder<int> intHolder:
DoIntThing(intHolder.Value);
break;
...
}
See also: Switch statements with patterns.
However, the idea behind polymorphism is to be able to do things without having to know the specific type. Therefore, re-design the holder classes and have them do the type specific thing themselves:
public abstract class Holder
{
public abstract void DoThing();
}
public abstract class Holder<T> : Holder
{
public abstract T Value { get; }
}
Some examples of specific types:
public class StringHolder : Holder<string>
{
public StringHolder(string value)
{
Value = value;
}
public override string Value { get; }
public override void DoThing()
{
Console.WriteLine($"String of length {Value.Length} is \"{Value}\"");
}
}
public class IntHolder : Holder<int>
{
public IntHolder(int value)
{
Value = value;
}
public override int Value { get; }
public override void DoThing()
{
Console.WriteLine($"The integer {Value} is {(Value % 2 == 0 ? "even" : "odd")}");
}
}
Now you can simply write
holder.DoThing();
... without having to cast.
Update
Your edited question indeed shows a polymorphic version.
Here I want to present another approach which merges Holder and Holder<T> in a single class through the use of interfaces.
public interface IHolder
{
object Value { get; set; }
}
public interface IHolder<T> : IHolder
{
new T Value { get; set; } // The new keyword hides the inherited property.
}
public class Holder<T> : IHolder<T>
{
object IHolder.Value
{
get => Value; // Returns T Holder<T>.Value as object.
set => Value = value is T t ? t : default; // Sets T Holder<T>.Value.
}
public T Value { get; set; }
}
Holder<T> now implements a "neutral" Value property declared in IHolder based on the object type. Since it implements it explicitly (i.e., instead of public object Value we write object IHolder.Value), this property is hidden, unless it is accessed through the interface. This allows you, for example, to declare a List<IHolder> and to retrieve different kinds of Holder<T> values with list[i].Value as object.
But you have a variable Holder<float> floatHolder, you can get the strongly typed float value.
Note that this still allows you do derive more specific types like class FloatHolder : Holder<float>, but it might not even be necessary.
If you intend to work only with derived types, you can mark Holder<T> as abstract and also all the members that must be implemented by the deriving classes. This makes it impossible to create an instance of Holder<T> with new and also allows you to declare abstract methods without body.
community! It's a good question. That was interesting.
I think this is simple solve for this question.
We just need to create a simple constructor like below
public class Holder
{
public string SomeData; // just example data
public Holder()
{
}
public Holder(Holder someData)
{
SomeData = someData.SomeData;
}
}
public class Holder<T> : Holder
{
public T Value;
public Holder(Holder a, T t = default)
:base(a)
{
Value = t;
}
}
public class Programm
{
void Main()
{
var h = new Holder();
var g = new Holder<string>(h);
}
}
This is my first time posting here and I'm rather new to programming, so I might not be fully understanding concepts which I intend to make use of such as interfaces or polymorphism.
I'm currently building a little game in which the player can select different types of objects and I'm struggling with coming up with a robust selection system. The way it works now is through an interface, which is implemented by every type of object the player can select.
public interface ISelectable
{
void DoSomething();
}
Then, this interface is used to call the implemented methods on the current selection based on different events such as mouse clicks or keys pressed.
public class Selector
{
public ISelectable selection;
public PerformAction()
{
selection.DoSomething();
}
}
The methods are implemented in different ways depending on the type of object. However, I've come across certain situations where I don't need a type of object to respond to an event, thus not needing to implement the method defined on the interface.
public class ObjectType1 : ISelectable
{
public void DoSomething() { /*Implemented*/ };
}
public class ObjectType2 : ISelectable
{
public void DoSomething() { /*Not needed*/ };
}
This has led me to believe that this may not be a correct approach to this. Therefore, I have a few questions:
Can my approach be fixed or improved so that it makes more sense and I don't encounter the situation described before again?
If not, is there a "correct" or simpler way to do this kind of selection system?
Thank you in advance. I will try to respond as fast as possible if any further clarification is needed.
Why does your ObjectType2 implement the interface ISelectable? You can remove it when it does not need it.
Or if you want a general interface, you can try these interface definitions:
public interface ISomeEmptyInterface
{
}
public interface ISelectable : ISomeEmptyInterface
{
void DoSomething();
}
Change the selector class:
public class Selector
{
public ISomeEmptyInterface myObj;
public void PerformAction()
{
if(myObj is ISelectable)
{
(myObj as ISelectable).DoSomething();
}
}
}
Classes implement the individual interface:
public class ObjectType1 : ISelectable
{
public void DoSomething()
{
Console.WriteLine("ObjectType1 is called");
};
}
public class ObjectType2 : ISomeEmptyInterface
{
// no any implementation
}
A simple program:
Selector sel1 = new Selector();
sel1.myObj = new ObjectType1();
sel1.PerformAction();
// output "ObjectType1 is called"
Selector sel2 = new Selector();
sel2.myObj = new ObjectType2();
sel2.PerformAction();
// not thing happened
This disadvantage is that your Selector must know what other sub ISomeEmptyInterface interfaces are.
I have the following classes set up like this:
class Test
{
public virtual subSmallObject CreateSmallObject
{
return new subSmallObject();
}
}
abstract class subSmallObject
{ string test; }
class subSmallObjectA : subSmallObject
{ string testA; }
class subSmallObjectB : subSmallObject
{ string testB; }
Now, instead of using Test class everywhere, I need to use a derived class of Test, let's call them class TestA and TestB. Test A and B need to have the CreateSmallObject class return either subSmallObjectA or SubSmallObjectB.
So typically I could just do
class TestA : Test
{
override subSmallObject CreateSmallObject()
{
return new subSmallObjectA();
}
}
class TestB : Test
{
override subSmallObject CreateSmallObject()
{
return new subSmallObjectB();
}
}
But the problem is that I can't then cast the subSmallObject return from those to subSmallObjectA or subSmallObjectB, due tot he requirements of the task at hand (it would break a lot of things that I don't have control over. Those things expect either smallSubObjectA or subSmallObjectB). There will be shared elements between subSmallObjectA and subSmallObjectB. I don't want to eliminate the virtual function because some code will be repeated if there are two separate methods.
Is there any pattern or any practice out there that I'm missing? I'm a bit lost on this and such architectural changes are beyond me, since I don't really know the "proper" way to do this.
Not being able to cast the results of a method call is...strange.
If you absolutely can't, you could try a generic factory method:
class SubObject{
public string Data;
}
class SubObjectA{
}
class SubObjectB{
}
class Test{
T GetSubObject<T>() where T:SubObject,new()
{
return new T();
}
}
Used Like
SubObjectA so=testInstance.GetSubObject<SubObjectA>();
That way you don't have to have the cast at the call site. It's not gonna work if SubObject doesn't have a default constructor though.
Is there a tool that can generate extract and generate interfaces for existing classes?
I know Visual Studio will extract an Interface for an existing class. However, I would also like to generate a wrapper class that implements that functionality.
I believe this would help tremendously for unit testing.
Example Existing Class:
public class ThirdPartyClass
{
public void Method1(){}
public void Method2(){}
}
This can be generated by Visual Studio (Extract Interface):
public interface IThirdPartyClass
{
void Method1();
void Method2();
}
I would like to go one step further:
public class ThirdPartyClassWrapper : IThirdPartyClass
{
private tpc = new ThirdPartyClass();
public void Method1()
{
tpc.Method1();
}
public void Method2()
{
tpc.Method2();
}
}
Update:
This would be especially useful for static classes. As Morten points out I can just use a stub, however, I would like to break up my coupling if possible.
Found a way around it for non-sealed classes.
1 - Inherit from the external class
class MyWrapper : ExternalClass
2 - Extract interface for all public methods
class MyWrapper : ExternalClass, IExternalClass
3 - Remove the inheritance from the external class
class MyWrapper : IExternalClass
4 - You will get a hint on the class name about members from the interface not being implemented. Alt + Enter on it and let Resharper automatically implement them
5 - Use this code template to wrap properties
get { return $INNERCOMPONENT$.$NAME$; }
set { $INNERCOMPONENT$.$NAME$ = value; }
6 - Use this code template to wrap methods
return $INNERCOMPONENT$.$NAME$($SIGNATURE$);
I don't know a tool that would do that for you.
You probably know, but Visual Studio goes just half step further - it can provide empty implementation of interface. I would stop there if it is one time task.
Depending on actual goal using some other way may work - i.e. for testing you can use mocking frameworks - usually there is a way to wrap existing class and override some methods as needed.
Another really slick way of doing this is to use Resharper to generate the "Delegating members" for you as described here: https://stackoverflow.com/a/2150827/1703887
Steps:
Create a new class that inherits from the class you want to wrap with a private variable of that class' type:
public class ThirdPartyClassWrapper : ThirdPartyClass
{
private ThirdPartyClass _ThirdPartyClass;
}
Do a Alt-Insert in/on the class to use Resharper to generate "Delegating members". Choose the methods you want to expose and pass through to the private variable.
If you have the free version of the GhostDoc extension installed you can highlight all of the created properties, methods, etc. and do a Ctrl-D to automatically grab all of the documentation from the base class and put it on the new members. (Resharper can do this too but I think you'd have to put "new" on each item which would then allow you to Alt-Enter and choose "Add xml-doc comments" from the Resharper popup menu).
You can then delete the base class and do some additional cleanup in case the method/property signatures expose any other types that you need to wrap.
What you are looking for is a stub, this can be done either by making your own stub implementation of the interface, or by using a mocking framework like Rhinomocks. Wrapping a difficult class in another class for testpurposes does nothing good for you.
Regards
Morten
I strongly suggest you look into a mocking framework like Fakeiteasy.
But to give you exactly what you asked for see below. I suspect ReSharper didn't have this operation when others answered.
add the interface to the class you wish to be the wrapping class
class MyWebElement : IWebElement { }
Find/Click "Delegate implementation of "YourInterfaceHere" to a new field
Select your options
Click finish and enjoy your new class
class MyWebElement : IWebElement
{
private IWebElement _webElementImplementation;
public IWebElement FindElement(By #by)
{
return _webElementImplementation.FindElement(#by);
}
public ReadOnlyCollection<IWebElement> FindElements(By #by)
{
return _webElementImplementation.FindElements(#by);
}
public void Clear()
{
_webElementImplementation.Clear();
}
public void SendKeys(string text)
{
_webElementImplementation.SendKeys(text);
}
public void Submit()
{
_webElementImplementation.Submit();
}
public void Click()
{
_webElementImplementation.Click();
}
public string GetAttribute(string attributeName)
{
return _webElementImplementation.GetAttribute(attributeName);
}
public string GetCssValue(string propertyName)
{
return _webElementImplementation.GetCssValue(propertyName);
}
public string TagName
{
get { return _webElementImplementation.TagName; }
}
public string Text
{
get { return _webElementImplementation.Text; }
}
public bool Enabled
{
get { return _webElementImplementation.Enabled; }
}
public bool Selected
{
get { return _webElementImplementation.Selected; }
}
public Point Location
{
get { return _webElementImplementation.Location; }
}
public Size Size
{
get { return _webElementImplementation.Size; }
}
public bool Displayed
{
get { return _webElementImplementation.Displayed; }
}
}
How can i check/evaluate the exact type of T without an object for T. I know my question maybe confusing but consider this...
public abstract class Business
{
public abstract string GetBusinessName();
}
public class Casino : Business
{
public override string GetBusinessName()
{
return "Casino Corp";
}
}
public class DrugStore : Business
{
public override string GetBusinessName()
{
return "DrugStore business";
}
}
public class BusinessManager<T> where T : Business
{
private Casino _casino;
private DrugStore _drugStore;
public string ShowBusinessName()
{
string businessName;
if (T == Casino) // Error: How can I check the type?
{
_casino = new Casino();
businessName = _casino.GetBusinessName();
}
else if (T == DrugStore) // Error: How can I check the type?
{
_drugStore = new DrugStore();
businessName = _drugStore.GetBusinessName();
}
return businessName;
}
}
I just want to have something like this on the client.
protected void Page_Load(object sender, EventArgs e)
{
var businessManager = new BusinessManager<Casino>();
Response.Write(businessManager.ShowBusinessName());
businessManager = new BusinessManager<DrugStore>();
Response.Write(businessManager.ShowBusinessName());
}
Notice that I actually didnt create the actual object for Casino and Drugstore when I call the BusinessManager, I just pass it as generic type constraint of the class. I just need to know exactly what Type i am passing BusinessManager to know what exactly the Type to instantiate. Thanks...
PS: I don't want to create separate specific BusinessManager for Casino and Drugstore..
You can also comment about the design.. thanks..
ADDITIONAL: and what if class Casino and DrugStore is an ABSTRACT CLASS =)
You can write
if(typeof(T) == typeof(Casino))
but really this type of logic is a code smell.
Here's one way around this:
public class BusinessManager<T> where T : Business, new() {
private readonly T business;
public BusinessManager() {
business = new T();
}
}
but personally I'd prefer
public class BusinessManager<T> where T : Business {
private readonly T business;
public BusinessManager(T business) {
this.business = business;
}
public string GetBusinessName() {
return this.business.GetBusinessName();
}
}
You should do
public class BusinessManager<T> where T : Business, new()
...
T _business = new T();
string businessName = _business.GetBusinessName();
return businessName;
I don't know about C# syntax, but is it not possible to do:
public class BusinessManager<T> where T : Business, new()
{
private T _business;
public string ShowBusinessName()
{
string businessName;
_business = new T();
return _business.GetBusinessName();
}
}
Since other guys have already shown various answers to your first question, I would like to address the second one: design.
1. Role of BusinessManager
Actual role of the BusinessManager class in your example is not too clear. Since this class is generic, and it shouldn't be concerned with the actual type of T, then it does nothing more than add another unnecessary layer between the Business class and the rest of the program.
In other words, you can simply use:
Business casino = new Casino();
Response.Write(casino.GetBusinessName());
Business drugStore = new DrugStore();
Response.Write(drugStore.GetBusinessName());
Wrapping this in another generic class doesn't help you a lot. On the other hand, if you want to have some common functionality for all these classes, you can either add it directly to your abstract class, or extract an interface and create extension methods for that interface.
2. Using properties for getters
Second thing, using a property is more appropriate when you have a simple getter method. In other words, you should replace GetBusinessName() method with a Name property (I also omitted the "Business" from the name because it is not necessary:
public interface IBusiness
{
string Name { get; }
}
public abstract class Business : IBusiness
{
public abstract string Name { get; }
}
public class Casino : Business
{
public override string Name
{
get { return "Casino Corp"; }
}
}
public class DrugStore : Business
{
public override string Name
{
get { return "DrugStore business"; }
}
}
And then you can use it like this:
IBusiness casino = new Casino();
Response.Write(casino.Name);
IBusiness drugStore = new DrugStore();
Response.Write(drugStore.Name);
Also, you can see that I have introduced a IBusiness interface. The reason for doing so is to allow you to implement this interface in more diverse ways. Right now, you will try to derive all your classes from the abstract Business class, and try to extract as much of the common functionality in the abstract class (that's the purpose of the class).
But extracting lots of common functionality comes with a cost: there is always a possibility that you will come up with a need to create a class which isn't derived from Business. If you are accessing all these methods through the IBusiness interface, then other parts of your program won't care if that implementation is derived from Business or not.
Since GetBusinessName really applies to the type and not instances of the type, you might consider using DescriptionAttribute (or your own BusinessNameAttribute) instead of an overridden property and have your BusinessManager get the business name from the attribute.
[Description("Casino Corp")]
public class Casino : Business
{
}
Now you no longer need to instantiate the business just to gets its name. To get the description, you use:
public string ShowBusinessName()
{
var attribute = Attribute.GetCustomAttribute(typeof(T), typeof(DescriptionAttribute)) as DescriptionAttribute;
if (attribute == null)
return "Unknown business";
return attribute.Description;
}
You can do something like this:
if (typeof(T) == typeof(SomeType))
{
// Same
}
define a BusinessManager class as bellow:
public class BusinessManager<T> where T : Business
{
Business biz;
public BusinessManager()
{
biz = new T();
}
public string ShowBusinessName()
{
return biz.GetBusinessName();
}
}
and use it as bellow:
var businessManager = new BusinessManager<Casino>();
Response.Write(businessManager.ShowBusinessName());
var anotherBusinessManager = new BusinessManager<DrugStore>();
Response.Write(businessManager.ShowBusinessName());
The way you using you will lost encapsulation
In VB.net you can use the GetType pseudo-function on a generic type parameter to get a reflection Type object. I would guess C# should have an equivalent. If for whatever reason you can't use something like that, you could create an array of 0 elements of the desired type, and then check the type of that array. That would probably be cheaper than instantiating an element of the unknown type.