I have a problem with declaring a type as passed from parameter type variable.
public static void ShowThisForm(Type passXtraForm, Form parent)
{
var xfrm = passXtraForm.GetType();
xfrm xfrmName = new xfrm();
xfrmName.Show();
}
Can I declare a variable as a type from passXtraForm.GetType() and declare it to another variable? Just passing the type of form to another class.
Thanks in advance for the response.
you could use generics for this:
public static void ShowThisForm<T>(T passXtraForm, Form parent) where T : Form, new()
{
T xfrmName = new T();
xfrmName.Show();
}
in this case the type argument is restricted to the Form type and types deriving from Form.
anyway, why are you having this method? there are other methods in the Form and Application static classes for finding the forms out there in your app...
First of all, it doesn't look like you need the parent parameter; I'd eliminate it entirely. Then I'd use generics to do what you're trying to accomplish:
public static void ShowThisForm<T>() where T : Form, new()
{
T xfrmName = new T();
xfrmName.Show();
}
The where T : Form, new() portion of this code is called a type constraint and it prevents you from calling the ShowThisForm method with a type that doesn't have a default constructor and derive from Form.
By indicating that T must have a default constructor, the compiler knows how to resolve new T(); by indicating that T derives from Form, the compiler knows how to call the .Show() method.
So, if you have a form class called MyForm, you could use the following syntax to call this method:
ShowThisForm<MyForm>();
For more documentation, you should take a look at these articles on MSDN:
Generic Methods
Constraints on Type Parameters
You could change it to something more like this:
public static void ShowThisForm<T>() where T : Form, new()
{
T xfrmName = new T();
xfrmName.Show();
}
Maybe pass in a factory, so that a known interface can instantiate what ever type of object the calling code deems is necessary?
(the below code is a quick sample I typed in here; formatting is off, and design could be better. It's just to give an idea)
static class XFactory
{
private int _id;
public XFactory(int formId) {
_id = formId;
}
/// <summary>
/// Decides which class to instantiate.
/// </summary>
public static Form Get()
{
switch (_id)
{
case 0:
return new FormA();
case 1:
case 2:
return new FormB();
case 3:
default:
return new FromC();
}
}
}
public static void Main()
{
ShowThisForm(new XFactory(2));
}
public static void ShowThisForm(XFactory formFactory)
{
var xfrm = formFactory.Get();
xfrm.Show();
}
You can instantiate a class/type via reflection and Activator.CreateInstance(typ, constructorargs), but most likely it would be better to create the object elsewhere and have it be of either a known base class (in your case it looks like form), or have it implement a defined interface that can be used to manipulate it. Very rarely will you need to create an object of totally unknown type.
Related
I'm having a generic function that returns a new instance of a subclass of AnyListVM implemented basically like this:
public TListVM MakeListVM<TListVM>()
where TListVM : AnyListVM
{
TListVM listVM;
switch(typeof(TListVM).ToString())
{
case nameof(EventListVM):
listVM = new EventListVM();
// some more init stuff
break;
// some more similar cases
default:
throw new NotImplementedException();
}
return listVM;
}
The two involved classes look currently like that, without any meaningful implementation yet:
public abstract class AnyListVM
{
}
public class EventListVM : AnyListVM
{
}
Now Visual Studio underlines my new EventListVM() and nags that it can't implicitly convert EventListVM to TListVM.
Okay, so I thought I simply add an explicit cast:
listVM = (TListVM)new EventListVM();
But nope. Now Visual Studio underlines it again and says that it's a redundant cast. The offered automatic fix would be to remove the cast again. Infinite loop.
What is going wrong here, why am I not allowed to do this cast, explicitly or implicitly?
There's one glaring thing in your implementation that is incorrect, which other's have pointed out but haven't addressed satisfactorily. If you intend to instantiate TListVM, then you need to change two very important parts. First the new code listing:
public TListVM MakeListVM<TListVM>()
where TListVM : AnyListVM, new()
{
TListVM listVM = new TListVM();
EventListVM evtList = listVM as EventListVM;
if (evtList != null)
{
// set evtList properties. You can't change
// the instantiation method.
}
// repeat for other constructs.
return listVM;
}
Now, to expound a bit. The generic where clause needs to specify that you intend to create the TListVM with a parameterless constructor. To do that, you need to specify new() as a generic constraint.
This greatly simplifies your implementation which only knows there is something called TListVM that has a base class of AnyListVM and has a constructor with no parameters. There's no need for a complicated switch statement, or using the Activator.
Any time you are dealing with generics, work with your generic parameter directly.
Based on further information, the switch statement is still the wrong tool. Generics necessarily constrain how you work with your object. You can't change the constructor, but you can specialize how you set properties after the object is instantiated.
Above I changed the listing to show how to set those properties directly.
If, instead you were dead set on having different constructors, etc. then you would have to approach it differently. You would have to return the base class and not TListVM.
public AnyListVM MakeListVM<TListVM>()
where TListVM : AnyListVM
{
return MakeListVM(typeof(TListVM)) as TListVM;
}
private AnyListVM MakeListVM(Type listVM)
{
AnyListVM listVM;
switch(listVM.ToString())
{
case nameof(EventListVM):
listVM = new EventListVM();
// some more init stuff
break;
// some more similar cases
default:
throw new NotImplementedException();
}
return listVM;
}
The generic helper method lets you wrap your more generic factory method so it has the signature you want, without causing compile errors.
You can't guarantee that EventListVM will convert to TListVM as according to your generic restriction, one is allowed to pass ANY inherited class of AnyListVM, which may or may not be EventListVM. Example, if the caller of this method did this:
AnyListVM vm = MakeListVM<SomeOtherListVMConcrete>();
It would fail, but shouldn't.
I believe what you really want is to cast your EventListVM to AnyListVM, the actual base type rather than the generic.
AnyListVM listVM = new EventListVM();
Still, if you are always returning an instance of EventListVM, I'd consider removing the generic clause all together and updating the signature to have a return type of EventListVM.
To make your problem more obvious, consider a base class and two children:
public class Base { } //AnyListVM
public class Child1 : Base{ } //EventListVM
public class Child2 : Base{ } //OtherListVM
now your method looks like:
public T Get<T>() where T : Base
{
//code
T item = new Child1();
//more code
}
Imagine I send in Child2, which is perfectly valid from the method signature. The method's code now looks like:
Child2 item = new Child1();
which of course is going to be invalid at compile time.
So let´s assume we have a Base-Assembly and a Custom-Assembly where every type within Base may or may not be overridden. So I have some code that creates a deep nested structure of some base-types. Now if I want to overwrite just some single type within this structure I would have to overwrite the whole structure to instantiate it. To ease this process I use a factory (as proposed here) that builds my inner-types.
public class MyFactory
{
private Assembly _customAssembly = // get custom-assembly;
private Type _actualType = null;
private static MyFactory _instance = new MyFactory();
private MyFactory()
{
// if we have custom assembly we search for classes that derive from our base-type
if (this._customAssembly != null) this._actualType = this._customAssembly.GetTypes().SingleOrDefault(x => x.BaseType == typeof(MyClass));
// no derived type found so use the base-type
if (this._actualType == null) this._actualType = typeof(MyClass);
}
/// <summary>
/// Gets an instance of either <see cref="MyClass"/> or an instance of a derived type of this class if there is any within the custom-assembly
/// </summary>
public static MyClass Create(string name) { return (MyClass)Activator.CreateInstance(MyFactory._instance._actualType, name); }
}
Now I can call the factory-method within my base-interface to create an inner-type. If this inner-type was derived within my custom-assembly I get an instance of that type instead of the base-type.
Now my question: As far as I know creating instances via reflection may take some time. Hence I´m creating such instances within a loop this may become a performance-relevant issue. I know that you may pimp up speed for invoking methods by using LINQ-Expressions (although I never did on my own). that point to the actual method. Thus we can directly invoke the method which may be much faster then using MethodInfo.Invoke. Is there any similar approach I can use to create new instances by declaring some kind of pointer to a constructor rather then a method?
Thanks for ya :)
You can use generics to do this:
public class MyFactory<T> where T : MyBaseClass
{
public static T Create(string name) { return new T{ Name = name }; }
}
I heard the word Interface Duck Typing, but do not understand at all what is it? So I read a wiki about this and they said:
In computer programming with object-oriented programming languages, duck typing is a style of typing in which an object's methods and properties determine the valid semantics, rather than its inheritance from a particular class or implementation of an explicit interface. The name of the concept refers to the duck test.
But still could not understand what it. So I saw their program but they use dynamic keyword to call quack() & feather() function of all the classes.
I would request you all please explain in easy way what is Interface Duck Typing and how to implement in C# v2.0 because there is no dynamic keyword.
using System;
namespace DuckTyping
{
public class Duck
{
public void Quack()
{
Console.WriteLine("Quaaaaaack!");
}
public void Feathers()
{
Console.WriteLine("The duck has white and gray feathers.");
}
}
public class Person
{
public void Quack()
{
Console.WriteLine("The person imitates a duck.");
}
public void Feathers()
{
Console.WriteLine("The person takes a feather from the ground and shows it.");
}
}
internal class Program
{
private static void InTheForest(dynamic duck)
{
duck.Quack();
duck.Feathers();
}
private static void Game()
{
Duck donald = new Duck();
Person john = new Person();
InTheForest(donald);
InTheForest(john);
}
private static void Main()
{
Game();
}
}
}
C# has a nominal type system, so the compatibility of types is done based on their names. In your example you have two classes with a Quack method, however there is no way to write a method which can take instances of these two classes and invoke their Quack method.
In C# 2, the solution would be to introduce an interface and have both classes implement it:
public interface IQuack
{
void Quack();
}
public class Duck : IQuack { }
public class Human : IQuack { }
now you can create a method which take an IQuack instance and can call Human.Quack and Duck.Quack through it. In C#, methods are resolved 'early' at compile time, so you need to create a named type which supports the operations the method need so the compilation can succeed. Note there is still a runtime element to calling these methods, since the real implementation of IQuack.Quack needs to be resolved at runtime depending on the real type of the argument.
In a duck-typing system, no attempt is made to validate that a method exists before runtime. All that is required is that a given object supports the operation in that it has the right name and takes the required number of parameters (none in this case), hence the 'if it quacks like a duck' expression.
Duck typing in C# 2 can only be done using reflection, in this case you would accept an object argument and look for the required methods yourself:
public static void MakeQuack(object duck)
{
MethodInfo quackMethod = duck.GetType().GetMethod("Quack", Type.EmptyTypes, null);
if (quackMethod!=null)
{
quackMethod.Invoke(duck, new object[] { });
}
else
{
throw new ArgumentException("No Quack() method found on target");
}
}
C#4 makes this much simpler with dynamic:
public static void MakeQuack(dynamic duck)
{
duck.Quack();
}
It would say it is a way of coding where the you tell the compiler:
"Hey trust me I know what methods and properties this object supports. You don't need to check them for me whilst I code."
Once you run your app the compiler will go:
"Ok lets see if I could trust you. Let me do some runtime binding."
If you then made a mistake, such as using an unsupported method, the compiler will shout: "Hey man, this is not supported! Check my RuntimeBinderException!"
Duck typing allows an object to be passed in to a method that expects
a certain type even if it doesn’t inherit from that type. All it has
to do is support the methods and properties of the expected type in
use by the method. I emphasize that last phrase for a reason. Suppose
we have a method that takes in a duck instance, and another method
that takes in a rabbit instance. In a dynamically typed language that
supports duck typing, I can pass in my object to the first method as
long as my object supports the methods and properties of duck in use
by that method. Likewise, I can pass my object into the second method
as long as it supports the methods and properties of rabbit called by
the second method. Is my object a duck or is it a rabbit? Like the
above image, it’s neither and it’s both. In many (if not most) dynamic
languages, my object does not have to support all methods and
properties of duck to be passed into a method that expects a duck.
Same goes for a method that expects a rabbit.It only needs to support
the methods and properties of the expected type that are actually
called by the method.
Please refer this to get an idea about Duck Typing
http://haacked.com/archive/2007/08/19/why-duck-typing-matters-to-c-developers.aspx/
About Duck Typing:
We don't need to know what the object is, but we just want to let the
object do something if it can do.
Example:
Example, if here are the things that we want the following objects do.
PleaseWalk(new Dog());
PleaseRun(new Duck());
PleaseWalk(new Cup());
PleaseFly(new Man());
PleaseFly(new Bird());
And, here is the result after we request the above objects do the things.
So, we don't need to check what the object is, but we can let it do something enough. Here is the code that I have written in C#.
private void PleaseWalk(object obj)
{
string Method = "Walk";
MethodInfo walkMethod = obj.GetType().GetMethod(Method, Type.EmptyTypes, null);
if (walkMethod != null)
{
walkMethod.Invoke(obj, new object[] { });
}
else
{
Console.WriteLine(string.Format("I can not {0} because {1}", Method, WhoAreYou(obj)));
}
}
private string WhoAreYou(object unknown)
{
MethodInfo whoAreYou = unknown.GetType().GetMethod("WhoAreYou", Type.EmptyTypes, null);
return whoAreYou.Invoke(unknown, new object[] { }).ToString();
}
You can use Events and exploit C# best suitable overload functions.
Hopefully, it will be useful :)
To get something Like a duck typing (.Net 4.+):
using System.Collections;
using System.Collections.Generic;
public interface IAny
{
void InvokeGetterEvent();
}
public class AnyValueTypeDuck<T, V> : IAny
where V : AnyValueTypeDuck<T, V>
{
public static event System.Action<V> GetterEvent;
public T Data;
public void InvokeGetterEvent()
{
GetterEvent.Invoke((V)this);
}
}
// Then create some concrete classes:
// Example :
public class LifeConcreteProperty : AnyValueTypeDuck<int, LifeConcreteProperty>
{
}
public class ManaConcreteProperty : AnyValueTypeDuck<float, ManaConcreteProperty>
{
}
// Now to finally use it :
public class UserClass
{
List<IAny> allDuckTypes = new List<IAny>();
public void GetDucketTypeClass(IAny anyDuckObject)
{
LifeConcreteProperty.GetterEvent += GetDucketType;
ManaConcreteProperty.GetterEvent += GetDucketType;
anyDuckObject.InvokeGetterEvent();
// it will propagate to event and will invoke
// best suitable overload method (GetDucketType)
LifeConcreteProperty.GetterEvent -= GetDucketType;
ManaConcreteProperty.GetterEvent -= GetDucketType;
}
public void GetDucketType(LifeConcreteProperty originalClass)
{
// Your efforts go here
int value = originalClass.Data;
}
public void GetDucketType(ManaConcreteProperty originalClass)
{
// Your efforts go here
float value = originalClass.Data;
}
}
I'm trying to create a class like Windows Form, which will have multiple new features. It's simply going to be a "better" version of Form, making my work easier on this exact program. Here's what I have so far:
public class SuperForm : Form
{
protected abstract void OnSizeChanged(object sender, EventArgs e);
public SuperForm()
{
this.SizeChanged += OnSizeChanged;
}
}
Not much, it only makes sure every Form will have to define OnSizeChanged which will be called automatically when size changes, but there's going to be more.
What I need next is a method which takes a class/type as it's parameter and initializes a new object of that type, automatically adds it to Controls and then returns the object. Here's an example code (not working) on how I would like it to be like:
public cls NewControl(ClassType cls) // This obviously doesn't work.
// I need it to return an object of type "cls" parameter.
{
cls newControl = new cls();
this.Controls.Add(newControl);
return newControl;
}
I know ClassType is not a valid type, that's why I need help.
And then I could basically call it like this:
Button b = this.NewControl(Button);
Which would return a new button and also add it to this.Controls. I might eventually need to do more of these common tasks when a control is initialized, so that's why I'd like to have it in it's own method.
Is this possible in C#? If not, are there any workarounds? One way would be to define a method for each class inheriting from Control like this:
public Button NewControl(Button b);
public TextBox NewControl(TextBox tb);
public ListBox NewControl(ListBox lb);
But it doesn't seem like a valid option to me.
It sounds like you want to make a generic method, with a couple of constraints on the type parameter:
public T CreateAndAdd<T>() where T : Control, new()
{
T newControl = new T();
Controls.Add(newControl);
return newControl;
}
Here the T : Control constraint makes sure that you're creating a control, so that you'll be able to use Controls.Add. The T : new() constraint makes sure the type argument has a public parameterless constructor, so that you can call new T().
To create a TextBox, for example, you would call the function like this:
var tb = CreateAndAdd<TextBox>()
(I've renamed the method for what I believe to be clarity, btw.)
I have the following function in c#:
bool Handle<TCommandHandler, TModel>(TModel model) where TCommandHandler : ICommandHandler<TModel> {
// ...
_container.Resolve<TCommandHandler>();
// ...
}
Since TModel is clear from a function parameter I want some way to not specify its type when calling a function. Ideally I want to call it like:
Handle<MyCommandHandler>(model);
Since this is probably impossible, I came up with the following:
HandleTemp<TModel> Handle<TModel>(TModel model) {
return new HandleTemp<TModel>(model);
}
public class HandleTemp<TModel> {
private TModel _model;
public HandleTemp(TModel model) { _model = model;}
public bool With<TCommandHandler>() where TCommandHandler : ICommandHandler<TModel> {
}
}
So I'm now calling it like:
Handle(model).With<MyCommandHandler>();
Are there other possibilities? Did I make something completely wrong with my solution?
No, your analysis and solution look about right. Indeed, generic type inference can work only on an all-or-nothing basis. If there are some generic parameters that can't be inferred, all must be explicitly stated. Personally I'd quite like a way to say "you worry about these parameters, I'll tell you this one", but... that doesn't exist.
The only other option is to add an artificial extra regular parameter to allow it to infer the generic parameter - a bit yucky.
One other option: challenge the assumption that generics are needed here. For example, could it just be a Type instance? Would:
bool Handle<TModel>(TModel model, Type type)...
...
Handle(model, typeof(MyCommandHandler));
work, for example? I can't answer this directly, as I don't know the particulars of your _container.Resolve<TCommandHandler>(); method, as to whether that could be adjusted to take a Type rather than a <T>.
All the C# compiler needs is a demonstration of the type in the arguments, so instead of attempting to place it in the generic arguments (at the usage site) make something that lets you provide an argument that helps the compiler identify that type. To make it less confusing, here is an example:
// Your classes/interfaces.
class Container
{
public static T Resolve<T>()
{
Console.WriteLine("Resolving {0}", typeof(T).FullName);
return default(T);
}
}
interface ICommandHandler<TModel>
{
void DoSomething();
}
// An implemented ICommandHandler.
public class WackyCommandHandler : ICommandHandler<string>
{
public void DoSomething() { }
}
// Used to help the C# compiler identify types.
public static class Identify
{
public static TypeIdentity<TType> TheType<TType>()
{
return null; // You don't actually need an instance.
}
}
public sealed class TypeIdentity<TType>
{
private TypeIdentity() { }
}
// Your method
static bool Handle<TCommandHandler, TModel>(TModel model, TypeIdentity<TCommandHandler> handler)
where TCommandHandler : ICommandHandler<TModel>
{
var item = Container.Resolve<TCommandHandler>();
return true;
}
// And the usage site:
var a = "hello";
Handle(a, Identify.TheType<WackyCommandHandler>());
Console.ReadLine();