Create hierarchical anonymous type - c#

Is there any way to create anonymous type that references instances of itself?
var root = new { Name = "Root", Parent = ??? };
var child = new { Name = "Child", Parent = root };
var childOfChild = new { Name = "Grand child", Parent = child };
For example, we can reference delegate from itself:
Action run = null;
run = () => run();
Another example, we can create generic Stack of anonymous types:
static Stack<T> CreateStack<T>(params T[] values)
{
var stack = new Stack<T>();
foreach (var value in values)
stack.Add(value);
return stack;
}
Can you think of any ways to reference anonymous type from itself?

Anonymous types in C# are immutable. Therefore all of their field values must have been present before the creation of the object and will never change. And therefore it is impossible to have a directly circular referencing anonymous type in C#.
Anonymous types in VB are mutable; you could probably figure out some way to do it in VB.
There might be a way to make an anonymous type indirectly reference itself, by, say, containing a delegate that when invoked, returns the instance of the anonymous type. I don't see any way off the top of my head to easily do that, but I also don't see a proof that doing so is impossible. Give it some thought and see what you come up with!
I assume this question is for entertainment purposes only. If you want to make a circularly-referential object, please make a nominal type.

It seemed... that the C# compiler will simply refuses to infer the type recursively. Take this sample code for example:
(From #Eric: Correct; the type inference engine requires that all the "input" types of a lambda be known before the "output" type of the lambda is inferred)
public void Run()
{
var k = Generator((str, parent) => new {
Name = str,
Parent = parent
});
}
public Func<string, T, T> Generator<T>(Func<string, T, T> generator)
{
return (str, obj) => generator(str, obj);
}
This snippet fails to compile with an error that the compiler cannot infer the <T> to use with Generator<T>... thus I think it's impossible.

Related

Get all types that are used as generic type arguments

Is it possible to get all types that are used as generic type arguments within certain assembly?
Basically, imagine I have this class:
public class Foo<T>
{
T SomeProperty {get; set;}
}
Now, I have an application and there I use the above in some way:
var stringFoo = new Foo<string>();
var intFoo = new Foo<int>();
Assume this is the only place the Foo is used. Now I would like to get type definitions of Foo<string> and Foo<int>. I.e. I want to find all types that are constructed from generic type definition (Foo<T>) within given assembly.
Is that even possible?
Correction... Still a pain... But no extra libraries needed. Now... On top of my head there are various places where you could find a type Foo<>:
attributes ([MyAttribute(typeof(Foo<>)], or perhaps Foo<> is in itself an Attribute)
base type chain (class MyClass : Foo<int>) or if Foo<> is a IFoo<> then implemented interfaces
members of a type (fields, properties, events, methods) (here I mean only the signature part of those, so the field type, the method arguments and return type...)
inner types of a type (types defined inside another type)
All of these can be found with "simple" application of reflection.
On top of these you can take a look at local variables of methods/properties (they are methods in the end), events (even they are methods in the end): if you have a MethodInfo method, you can get a MethodBody body = method.GetMethodBody(), and the MethodBody defines a LocalVariables.
Note that without disassembling the code (for example with Mono.Cecil) you won't be able to detect that in
public class C
{
public List<int> MyList;
public void M()
{
MyList = new List<int>();
Console.WriteLine(new List<int>());
}
}
the method M uses a List<int>(), because no local variable of type List<int> is used. So in the end you'll need to even disassemble all the methods.
Clearly each time you find a type, you must check if the type is a Foo<>, a subclass of Foo<>, or perhaps uses Foo<> as a parameter (List<Foo<>>), or is a pointer Foo<>*, or a managed pointer ref Foo<> or...)
As far as variables is concerned, you could discover the types by examining the method.
public static void GetGenericVariables()
{
//Declaring two variables here that use Foo<>
var inttype = new Foo<int>();
var stringType = new Foo<string>();
var methodInfo = typeof(ClassContainingMethod).GetMethod("GetGenericVariables");
var variables = methodInfo.GetMethodBody().LocalVariables;
foreach (var variable in variables)
{
if (variable.LocalType.IsGenericType && variable.LocalType.GetGenericTypeDefinition() == typeof(Foo<>))
{
Console.WriteLine(variable.LocalType.GenericTypeArguments[0].FullName);
}
}
}
Output:
System.Int32
System.String
You would have to recurse over the assemblies and types though.

Pass Type to IQueryable at runtime

Is it possible to pass type to IQueryable to realize at run time.
Like,
//Get type at runtime
Type type = Type.GetType("fully qualified class name");
IQueryable<type> test = // <-returned object of this type
Actual problem as below:
Below I am able to get right side object with specific type, but that is not casting to type of query variable. Also I will have known type for query.
Dictionary<string, Type> myDictionary = new Dictionary<string, Type>()
{
{ "tableName", typeof(tableName) }
};
//Below I am able to get right side object with specific type, but that is not casting to type of query variable. Also I will have known type for query.
IQueryable<Type> query= EFContext.Set(myDictionary[tableName]).AsQueryable();
Later using this query object to select data by passing select/where condition dynamically.
var data = query.Select(x=> new
{
id= x.id,
name= x.name .. etc
}).ToList();
Later I need to use this test variable to dynamically query data.
Also please suggest any alternative to resolve this scenario.
If you have an example of the IQueryable type you need, you can use an generic method to capture the type - this one returns a null of the proper type:
public static T NullByExample<T>(this T _) where T : class => (T)null;
If you have an example of the items returned, you can use an extension like:
public static IEnumerable<T> EmptyByExample<T>(this T _) => Enumerable.Empty<T>();
Either use AsQueryable on the result:
var test = EmptyByExample(classObject).AsQueryable();
or create an IQueryable variant - unfortunately, there isn't really an IQueryable equivalent to Enumerable.Empty:
public static IQueryable<T> EmptyQueryByExample<T>(this T _) => Enumerable.Empty<T>().AsQueryable();
var test = EmptyQueryByExample(queryObject);
Otherwise, as mentioned, you are in the world of reflection, which probably indicates you are doing something wrong. The problem is you will find you can only get test to be of type object in that case, because the compiler can't know what type represents and e.g. var is a compile time shorthand, unless you want to use dynamic (and you shouldn't do that either).
There are ways to do what you're asking via reflection, but maintainability will be limited. You're probably better off creating a shared interface to your types and writing a generic method, something like this:
interface IMyInterface
{
string SomeProperty {get;set;}
}
class MyClass : IMyInterface
{
public string SomeProperty {get;set;}
}
IQueryable<T> SomeMethod<T>() where T : IMyInterface, new()
{
var result = new List<T>() {
new T() { SomeProperty = "a"},
new T() { SomeProperty = "b"}
};
return result.AsQueryable();
}
So a call to the generic method might be:
var temp = SomeMethod<MyClass>();

How do you declare a Func with an anonymous return type?

I need to be able to do this:
var getHed = () =>
{
// do stuff
return new { Property1 = value, Property2 = value2, etc...};
};
var anonymousClass = getHed();
But I get an error which indicates I need to explicitly declare getHed.
How do I declare Func such that T is the anonymous type I am returning?
In case you are curious why I need to do this, it is because I am using 3rd party software that allows customization code, but only within a single method. This can become very difficult to manage. I had the idea that I could use anonymous methods to help keep the procedural code organized. In this case, for it to help, I need a new class, which I cannot define except anonymously.
As is basically always the case with anonymous types, the solution is to use a generic method, so that you can use method type inference:
public static Func<TResult> DefineFunc<TResult>(Func<TResult> func)
{
return func;
}
You can now write:
var getHed = DefineFunc(() =>
{
// do stuff
return new { Property1 = value, Property2 = value2, etc...};
});
Use the following generic method to let the compiler infer the anonymous type for you:
public static Func<T> MakeFn<T>(Func<T> f)
{
return f;
}
Usage:
var getHed = MakeFn(() => new { Property1 = ..., Property2 = ... });
var anonymousClass = getHed();
// you can now access Property1 and Property2
var test = anonymousClass.Property1;
In short, it can't be done.
You need an additional, generic, method to trick the compiler into inferring the T for you to be the anonymous type, such as the other answers here provides.
However, since you've written that this is a special case where everything has to fit inside a single method, then no, it cannot be done.
The compiler does not allow this syntax:
var x = () => ...
It needs this:
DelegateType x = () => ...
As such, you need to trick the compiler into working out the right type for DelegateType, which likely is Func<(anonymous type here)>, and this can only be done through type inference.
However, type inference and generic parameters requires the method to be generic, and thus the need for the additional method that has to be a generic method to help the compiler do this type inference.
Since you need to stay inside one method...

How to specify the type of an anonymous type while using a generic type

The title is pretty confusing. I will try to explain with an example. Consider the code below:
String[] str={"Apple","Banana","Cherry","Orange"};
var anoCollection=from e in str select new
{
ch=e[0],
length=e.Length
}
dataGridView.DataSource=anoCollection.ToList(); //TypeInitializationException
I feel that I need to mention the type in above case for the ToList<T>() method. But how can I mention an anonymous type here?
It is never possible to mention an anonymous type directly, but you should not need to. Generic type inference means that you don't need to specify the <T> in .ToList<T>() - the compiler will automatically inject the invented type.
There are only a few ways to refer to an anonymous type:
via someObj.GetType(), where someObj is an instance of an anonymous type
via generics, as a T, by calling a generic method via generic type inference (as in ToList())
various other usages of reflection, pulling in the T via GetGenericTypeParameters()
This may be not what you are asking for, but if you later want to use the DataBoundItem for a row, you can do it this way:
var item = TypeExtensions.CastByPrototype(row.DataBoundItem, new { ch = 'a', length = 0});
//you can use item.ch and item.length here
Trace.WriteLine(item.ch);
with the support of this method:
public static class TypeExtensions
{
public static T CastByPrototype<T>(object obj, T prototype)
{
return (T)obj;
}
}

Returning desired type from Activator.CreateInstance() instead of object

I'm trying to create an instance of specified Type whatever user wants to have. For a quick illustration of my purpose please see the code below:
static void Main(string[] args)
{
object o = GetInstance(typeof(int));
Console.WriteLine("Created type: {0}", o.GetType().FullName);
}
public static object GetInstance(Type t)
{
Console.WriteLine("Creating instance of {0}", t.FullName);
return Activator.CreateInstance(t);
}
The problem is Activator.CreateInstance() returns object by default. There is also an overload of this method like T Activator.CreateInstance<T>() which is parameterless and returns the type you specify as T.
However, the problem is T should be hard-coded while calling this method and thus should be a fixed value. I am trying to create an instance of desired class and return it as its type.
Right now if you use this method you should write something like:
int i = GetInstance(typeof(int)) as int
I'm trying to reduce this to:
int i = GetInstance(typeof(int))
Is there a way that I can do casting inside the GetInstance and get rid of that as int repetition? By this way, my return type (and also the type I cast the object to) will be unknown at compile time.
Seemed impossible by design to me but I'd really appreciate if you figure it out.
EDIT: Where I'm stuck is e.g. while you're casting, you can do return (T) result if you are in a generic method, but you can't do Type t = ...; return (t) result this doesn't work. You cannot cast to a type which is passed to you as a parameter which is not known at compile time.
Follow a known pattern
This is not a new problem. It is a problem facing any API that allows type-specific return values. For example, a JSON parsing library like Newtonsoft (which is, to wit, the single most popular .NET package downloaded by .NET programmers in 2019) must be able to parse a string and return a type-specific object, which may or may not be known at compile time. It might make sense to follow their example.
Newtonsoft exposes three ways to specify the type when deserializing. You could do as you are currently doing:
//Cast required
var result = JsonConvert.DeserializeObject(text, typeof(MyType)) as MyType;
You can use a generic method:
//No cast required, but you have to hardcode a type as a type parameter
var result = JsonConvert.DeserializeObject<MyType>(text);
Or you can use an instance as a template, which is great for anonymous types, although you can use it with non-anonymous classes as well. This one works via generic type inference:
//No cast required and no need to specify type; the type is inferred from the argument
var result = JsonConvert.DeserializeAnonymousType(text, new MyType());
Here's how you'd do it:
So for you to make this work, your code might look like this:
public object GetInstance(Type type)
{
return Activator.CreateInstance(type);
}
int i = GetInstance(typeof(int)) as int;
public T GetInstance<T>()
{
return Activator.CreateInstance<T>();
}
int i = GetInstance<int>();
public T GetInstance<T>(T template)
{
return Activator.CreateInstance<T>();
}
int i = GetInstance(0);
If you do it this way, it's hard to imagine any programmer would have trouble using your library, as the approach should already be familiar to them.
Actually you could write GetInstance like this:
static T GetInstance<T>()
{
return Activator.CreateInstance<T>();
}
And use it:
int j = GetInstance<int>();
This might help you to create instance of desired type:
public class ConcreteFactory<T> : AbstractFactory<T>
{
public override T CreateInstance(string typeName,params object[] parameters)
{
var path = Assembly.GetExecutingAssembly().CodeBase;
var assembly = Assembly.LoadFrom(path);
var type = assembly.GetTypes().SingleOrDefault(t => t.Name == typeName);
return (T)Activator.CreateInstance(type, parameters);
}
}
Key here is generic type T can be used to cast the created instance, this can be used as a template to create instance of any type with parameterized constructor

Categories

Resources