Method with Generic Type, set value - c#

I have a method which is something like below and i want to set the value of it with input string.
How would i go about it? Any advice will be greatly appreciated
private static void QueueCheckNAdd<T>(ref T param, string input)
{
param.DoSomethingLikeSetValue(input);
}
for your reference, the generic type is something like int or double

param = (T)(object)Convert.ChangeType(input, typeof(T));
The casts are necessary to convince the compiler that the result is really of type T.

You want param to be generic (i.e., any type), and you expect to be able to call some method on it, correct? Well, you can see the problem there: if param can be any type, there's no way to guarantee that it will have the method DoSomethingLikeSetValue (or whatever). I'm sure you could get fancy with introspection or runtime type coercion, but I think the "clean" way to do what you're looking for is to constrain the type of T to some interface that has the required method (DoSomethingLikeSetValue). Like this:
private static void QueueCheckNAdd<T>(ref T param, string input) where T : IHasSomething {
param.DoSomethingLikeSetValue(input);
}
public interface IHasSomething {
void DoSomethingLikeSetValue(string s);
}
Then you can invoke QueueCheckNAdd generically only if the generic type supports the IHasSomething interface. So you could use it like this:
public class Foo : IHasSomething {
public void DoSomethingLikeSetValue(string s) {
Console.WriteLine(s);
}
}
var f = new Foo();
QueueCheckNAdd<Foo>(f, "hello");

Good practice would be to use interface like described before,
But if you want some fun, you could aslo use the object as a dynamic object, like below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class SMTHG
{
public void DoSomethingLikeSetValue(string input)
{
Console.WriteLine("HEYYYYY!!! DYNAMIC OBJECTS FTW!...\n" + input);
}
}
class Program
{
private static void QueueCheckNAdd<T>(ref T param, string input)
{
dynamic dynamicObject = (dynamic)param;
dynamicObject.DoSomethingLikeSetValue(input);
}
static void Main(string[] args)
{
SMTHG smthg = new SMTHG();
QueueCheckNAdd(ref smthg, "yoyuyoyo");
}
}
}

Related

Exception using GetFunctionPointerForDelegate: "The specified Type must not be a generic type definition. "

Trying to use GetFunctionPointerForDelegate to pass a function pointer over interop, (C# -> C++). However, I am getting the exception: The specified Type must not be a generic type definition.
As far as I can tell I am not passing in a generic type definition, when inspecting the type of the delegate I saw the following:
I wrote a minimum example and observed the same behaviour, would appreciate any advice as to what I'm missing.
using System;
using System.Runtime.InteropServices;
public class MyTestClass
{
public void Foo()
{
Delegate del = new Func<int, int>(Bar);
IntPtr funcPtr = Marshal.GetFunctionPointerForDelegate(del);
}
public int Bar(int a)
{
return 0;
}
}
public class Program
{
public static void Main()
{
var mtc = new MyTestClass();
mtc.Foo();
}
}
The issue can be observed on dotnet fiddle: https://dotnetfiddle.net/8Aol9j
Read the error and try like this net fiddle:
delegate int BarFunc(int a);
public void Foo()
{
BarFunc del = Bar;
IntPtr funcPtr = Marshal.GetFunctionPointerForDelegate(del);
}
public int Bar(int a)
{
return 0;
}
The new Func<int, int> declaration IS a generic type. To avoid this, declare a delegate type and assign as indicated in the sample code and the fiddle.

Can I create a generic method with generic input TInput and generic output TOut in c#

Can I create a generic method with generic input(TInput) and generic output(TOutput) in c# or any alternative for this kind of scenario?
You mean a generic method? Just use the generic <T> behind the declaration of the method name, like: (ofcourse the input type specification is unnecessary in this example, because the Convert.ChangeType uses an object as parameter)
public static TOutput ConvertTo<TInput, TOutput>(TInput input)
{
return (TOutput)Convert.ChangeType(input, typeof(TOutput));
}
Usage:
int myInt = 10;
double myDouble = ConvertTo<int, double>(myInt);
Yes.
Here is an example:
using System;
namespace GenericInOut {
class Test<In, Out> {
public Out Afunc(In x) {
return default;
}
}
class Program {
static void Main(string[] args) {
var t = new Test<int, string>();
Console.WriteLine($"output is default for string {t.Afunc(3)}");
}
}
}
Is that the extent of your question? You may want to be more specific if you want greater detail in your answers.

Shimming object that doesn't have constructor [duplicate]

Take the following class as an example:
class Sometype
{
int someValue;
public Sometype(int someValue)
{
this.someValue = someValue;
}
}
I then want to create an instance of this type using reflection:
Type t = typeof(Sometype);
object o = Activator.CreateInstance(t);
Normally this will work, however because SomeType has not defined a parameterless constructor, the call to Activator.CreateInstance will throw an exception of type MissingMethodException with the message "No parameterless constructor defined for this object." Is there an alternative way to still create an instance of this type? It'd be kinda sucky to add parameterless constructors to all my classes.
I originally posted this answer here, but here is a reprint since this isn't the exact same question but has the same answer:
FormatterServices.GetUninitializedObject() will create an instance without calling a constructor. I found this class by using Reflector and digging through some of the core .Net serialization classes.
I tested it using the sample code below and it looks like it works great:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Runtime.Serialization;
namespace NoConstructorThingy
{
class Program
{
static void Main(string[] args)
{
MyClass myClass = (MyClass)FormatterServices.GetUninitializedObject(typeof(MyClass)); //does not call ctor
myClass.One = 1;
Console.WriteLine(myClass.One); //write "1"
Console.ReadKey();
}
}
public class MyClass
{
public MyClass()
{
Console.WriteLine("MyClass ctor called.");
}
public int One
{
get;
set;
}
}
}
Use this overload of the CreateInstance method:
public static Object CreateInstance(
Type type,
params Object[] args
)
Creates an instance of the specified
type using the constructor that best
matches the specified parameters.
See: http://msdn.microsoft.com/en-us/library/wcxyzt4d.aspx
When I benchmarked performance of (T)FormatterServices.GetUninitializedObject(typeof(T)) it was slower. At the same time compiled expressions would give you great speed improvements though they work only for types with default constructor. I took a hybrid approach:
public static class New<T>
{
public static readonly Func<T> Instance = Creator();
static Func<T> Creator()
{
Type t = typeof(T);
if (t == typeof(string))
return Expression.Lambda<Func<T>>(Expression.Constant(string.Empty)).Compile();
if (t.HasDefaultConstructor())
return Expression.Lambda<Func<T>>(Expression.New(t)).Compile();
return () => (T)FormatterServices.GetUninitializedObject(t);
}
}
public static bool HasDefaultConstructor(this Type t)
{
return t.IsValueType || t.GetConstructor(Type.EmptyTypes) != null;
}
This means the create expression is effectively cached and incurs penalty only the first time the type is loaded. Will handle value types too in an efficient manner.
Call it:
MyType me = New<MyType>.Instance();
Note that (T)FormatterServices.GetUninitializedObject(t) will fail for string. Hence special handling for string is in place to return empty string.
Good answers but unusable on the dot net compact framework. Here is a solution that will work on CF.Net...
class Test
{
int _myInt;
public Test(int myInt)
{
_myInt = myInt;
}
public override string ToString()
{
return "My int = " + _myInt.ToString();
}
}
class Program
{
static void Main(string[] args)
{
var ctor = typeof(Test).GetConstructor(new Type[] { typeof(int) });
var obj = ctor.Invoke(new object[] { 10 });
Console.WriteLine(obj);
}
}

How to cast object to generic class without knowing T

I get my variable from var pi = propertyInfo.GetValue(instance)
this is an object Type. I know all result of this are of type
ObjectSet<TEntity> . I don't know TEntity. TEntity is allways different.
The consuming function looks alike:
BuildClassItem<T>(ObjectSet<T> entities, ... ) where T : class
How can I cast object to ObjectSet ?
I tried alredy this. But I don't know T
public static ObjectSet<T> MyConvert<T>(object myInput) where T : class
{
return (ObjectSet<T>)myInput;
}
You can use System.Linq.Expressions to construct a "trampoline" - a call into a method which is generic. Once you're inside that generic method, then you can start using T naturally when you need to talk about the type. Here I'm using BuildClassItem directly as the target for the trampoline:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace Exercise
{
class Program
{
static void Main(string[] args)
{
var obj = GetObjectSet();
//We know obj is an ObjectSet<T> for unknown T
var t = obj.GetType().GetGenericArguments()[0];
var parm = Expression.Parameter(typeof(object));
var objectSet = typeof(ObjectSet<>).MakeGenericType(t);
var method = typeof(Program).GetMethod("BuildClassItem", BindingFlags.Static | BindingFlags.NonPublic).MakeGenericMethod(t);
var trampoline = Expression.Lambda(
Expression.Call(null, method, Expression.Convert(parm,objectSet)), new[] {parm});
var dele = (Action<object>) trampoline.Compile();
dele(obj);
Console.WriteLine("Done");
Console.ReadLine();
}
static void BuildClassItem<T>(ObjectSet<T> entities) where T : class
{
Console.WriteLine("We made it!");
}
static object GetObjectSet()
{
return new ObjectSet<string>();
}
}
internal class ObjectSet<T> where T:class
{
}
}
If you have more work to do between finding the type T and calling BuildClassItem you'd still want to put all of that logic inside a generic method in T and construct a void call into it. You can't "say" the name of the type from outside a generic method so you have no way of storing the returned value from your MyConvert function in a correctly typed variable. So you need to move all of the logic into it.
public class ObjectSet<T>
{
}
public static ObjectSet<T> MyConvert<T>(object myInput) where T : class
{
return (ObjectSet<T>)myInput;
}
invoke like this :
ObjectSet<object> get = MyConvert<object>(new ObjectSet<object>());
I'm not got any error , So what error for your case ??
or
public class FOO
{
}
public interface IObjectSet
{
}
public class ObjectSet<T> : IObjectSet
{
}
IObjectSet get = MyConvert<FOO>(new ObjectSet<FOO>());

Does C# support a __call__ method?

Python has this magic __call__ method that gets called when the object is called like a function. Does C# support something similar?
Specifically, I was hoping for a way to use delegates and objects interchangeably. Trying to design an API where a user can pass in a list of functions, but sometimes those functions need some initial params, in which case they'd use one of those callable objects instead.
Sure, if you inherit from DynamicObject. I think you're after TryInvoke which executes on obj(...), but there are several other method you can override to handle casting, index access (obj[idx]), method invocations, property invocations, etc.
using System;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Text;
namespace ConsoleApplication {
public static class ConsoleApp {
public static void Main() {
dynamic x = new MyDynamicObject();
var result = x("awe", "some");
Debug.Assert(result == "awesome");
}
}
public class MyDynamicObject : DynamicObject {
public override Boolean TryInvoke(InvokeBinder binder, Object[] args, out Object result) {
result = args.Aggregate(new StringBuilder(), (builder, item) => builder.Append(item), builder => builder.ToString());
return true;
}
}
}
I bow to Simon Svensson - who shows a way to do it if you inherit from DynamicObject - for a more strait forward non dynamic point of view:
Sorry but no - but there are types of objects that can be called - delegates for instance.
Func<int, int> myDelagate = x=>x*2;
int four = myDelagate(2)
There is a default property though - that has to have at least one parameter and its access looks like an array access:
class Test1
{
public int this[int i, int j]
{
get { return i * j; }
}
}
Calling
Test1 test1 = new Test1();
int six = test1[2, 3];
Then you can do some really silly stuff with delegates like this:
class Test2 // I am not saying that this is a good idea.
{
private int MyFunc(int z, int i)
{
return z * i;
}
public Func<int, int> this[int i] { get { return x => MyFunc(x, i); } }
}
Then calling it looks weird like this:
Test2 test = new Test2();
test[2](2); // this is quite silly - don't use this.....
This would be akin to overloading the function call operator (as is possible in C++). Unfortunately, this is not something which is supported in C#. The only objects that can be called like methods are instances of delegates.

Categories

Resources