How to pass a Type to a method for a return of the same type
Struggling to find the right syntax for this. I'm trying to specify a type that should be used to create a new instance and then return it. Example code (doesn't compile):
In this instance, the constructors of each Type I'll be passing will receive the XElement and subsequently update its properties from the XElement.
Example calls would be:
the
return new...
is essentially return new Server(XElement)
and return new User(XElement)
(if that makes sense?)
(I know I'm assigning it to an object, but don't worry about that bit!)29 Replies
If you need to create an instance of T, it needs to be listed as a constraint
void foo<T>() where T : new()
though not the most flexible approach as it assumes the type has an parameterless constructor
With the constraints, you can instanciate T like any other type T t = new()
You can also use Activator.CreateInstance
although that's not type safe
With requiring XElement, you can also consider exposing it through a common interface and adding that interface as a constraint to assign the value void foo<T>() where T : ISomeInterface
Hmm. SO I tried:
but getting compile error: "cannot provide arguments when creating an instance of a variable type"
Or receiving a construction delegate
The new() constraint only works for parameterless consturctors and you can't constraints based on constructors with parameters
If you were to refactor your classes, the new() constraint can server as a starting point to create the object from there you can assign the XElement through other means
Through a construction delegate:
T foo<T>(Func<string, T> ctor) => ctor("arg");
That grants more flexibility over constructors, even supporting static creation methodsAll the relevant Types have a public method called
UpdateFromXElement
- however - tried this - also doesn't compile:
(forgive me - I'm a hobby coder)To use anything with a generic type, it needs to be specified through a constraint.
new()
is one that allows creating objects, but you also need constraints for the members you access. In your case, an common interface that defines the method you want to use
void foo<T>() where T : ISomeInterface
and the interface would have the
UpdateFromXElement
method specified presumably?Yes, and have each of the clases implement that interface
Also I don't know your code but you would likely want to call
UpdateFromXElement
first then return obj
Defining multiple constraints: void foo<T>() where T : new(), InterfaceA, InterfaceB
Hmmm
What is the error on new()? I remember there's a specific order, maybe I had it the wrong way around
^ my bad
ok
Other comile error is:
Because the method is void and you're returning from the call
Should be distinct, calling it then returning obj
ohbloody hell yes!
Let me take it for a spin
:spinning_think:
Perfect!
:HYPERSclap:
Cheers dude! Now I got some serious reading to do about "constraints" - new one to me
tl;dr The generic system is based on better safe than sorry, so assumes the worst that T is
System.Object
unless constrainted to something more specificand of course, generic Object has no custom Methods, so the constraint tells the method what you can and can't do with T? (e.g. new it up or use a method defined via an interface?) - layman's terms
hah - so it "constrains T" from generic to some kind of ball park - awesome!
Thanks for all your help. 👍
Just watch out when getting nullability involved shivers from flashbacks - varying actual types depending if T is struct or class
not easy to debug?
More of a beginner's trap
then I'll definitely end up in it 😉
Damn - this is quite powerful - given it's an interface the common method can be different in each class 🤯
In recent .NET, static interface members are also suppoted
For anything numbers, there's the new
System.Numerics
as a backbone of every numeric typetbh, I still feel like I need to learn to toddle before I try to break into a sprint!