Answered by:
How to use ananomous class with method takes generic class

Question
-
Hi Everyone,
I have a question how to use ananomous class with method takes generic class. Here is what I want to do but not sure how to make this one works.
private
T DoSomething<T>(T myObj)
{
// do something with myObject then return that object
return myObj;
}
var customer = new { Name = "SomeOne", Address = "12345 Some Street", City = "MyCity" };
customer = DoSomething< AType>(customer )
Currently, I have no idea what should be replace "AType" I tried
Type myType = customer.GetType() ;
customer = DoSomething< myType>(customer );
but the compiler dos not like it.
Any idea how to make this works?
Regards,
JdangMonday, August 10, 2009 3:03 PM
Answers
-
You may also consider not using the anonymous type. The sole purpose of anonymous types is to make your life simple. If instead it's giving you a hard time, then just don't use them.
I'm not so sure about the "no need for generics". That method does give type safety compared to the non-generic version that would look something like this: object GetObject (Type objType, string sql).
Hope it helps,
Fernando.
I always try to Keep it Sharp & simple.- Proposed as answer by Michael Sun [MSFT]Microsoft employee Friday, August 14, 2009 5:12 AM
- Marked as answer by Michael Sun [MSFT]Microsoft employee Tuesday, August 18, 2009 1:25 AM
Monday, August 10, 2009 8:12 PM -
Omitting the type argument from the generic function method call will only work if the compiler can deduce the type argument from the method arguments. That won't work if you pass a string.
Passing a fake argument to help won't work. You will have to create a real instance of T as the return value and that requires the new() constraint. Now passing the fake anonymous type doesn't work anymore since it doesn't have a public constructor.
You can't use a generic method to create an anonymous type object.
Hans Passant.- Proposed as answer by Michael Sun [MSFT]Microsoft employee Friday, August 14, 2009 5:12 AM
- Marked as answer by Michael Sun [MSFT]Microsoft employee Tuesday, August 18, 2009 1:25 AM
Monday, August 10, 2009 8:48 PM -
Hi Jdang,
I agree with nobugz that the compiler should first know the generic type information passed in. The SQL select string won’t tell the compiler the type information. What if we passed the T type into the generic method or extension method?
==================================================
public static T GetObject<T>(this T obj, string selectText)
==================================================We get the anonymous type object, its type, and the selectText, but I think we still cannot return the anonymous type object successfully. Your GetObject method reminds me some LINQ to SQL method like DataContext.ExecuteQuery<T>. The following method will throw some exception like the anonymous type does not define a parameterless constructor in order to be constructed during mapping.
==================================================
public static T GetObject<T>(this T obj, string selectText)
{
MyDataContext db = new MyDataContext();
return db.ExecuteQuery<T>(selectText).First();
}
==================================================
If we use .NET Reflector to check the implementation of the anonymous type, we find that they are realized by some internal sealed types with compiler-generated names. They have private readonly fields, public readonly properties, a public constructor with fields as parameters, overridden Equals, GetHashCode, and ToString methods. Because the names of the readonly fields are generated by the compiler, we cannot know the names in advance. In GetObject method, it seems that we can only access the readonly fields by calling the constructor to create new anonymous type object via Reflection.If Student object contains two properties, StudentID, and Name, then these codes may return the first row information inside the Student data table.
===================================================
var student = new { StudentID = 0, Name = "" };var newstudent = student.GetObject("SELECT * FROM [Student]");
public static class MyExtensionMethod
{
public static T GetObject<T>(this T obj, string selectText)
{
MyDataContext db = new MyDataContext();
var s = db.ExecuteQuery<Student>(selectText).First();
var constructor = obj.GetType().GetConstructor(new Type[] { typeof(int), typeof(string) });
return (T)constructor.Invoke(new object[] { s.StudentID, s.Name });
}
}
===================================================
However, I am afraid that such codes are totally away from our original design goal of anonymous type and your generic method with anonymous type. Hope my post can help you understand clearer.
Have a nice day!
Best Regards,
Lingzhi SunMSDN Subscriber Support in Forum
If you have any feedback on our support, please contact msdnmg@microsoft.com
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.- Proposed as answer by Michael Sun [MSFT]Microsoft employee Friday, August 14, 2009 5:13 AM
- Marked as answer by Michael Sun [MSFT]Microsoft employee Tuesday, August 18, 2009 1:25 AM
Tuesday, August 11, 2009 7:50 AM
All replies
-
Why do you feel the need for generics?
Mark the best replies as answers. "Fooling computers since 1971."Monday, August 10, 2009 3:18 PM -
It's a long story and the method that take a generic type is very usefull to our oragization right now. I wish we can make this works with ananomous object.
regrards,
JdangMonday, August 10, 2009 3:22 PM -
Just omit the generic type argument. The compiler can deduce it from the argument type:
using System;
class Program {
static void Main(string[] args) {
var anon = new { Name = "nobugz" };
var anon2 = DoSomething(anon);
}
static T DoSomething<T>(T myObj) { return myObj; }
}
Hans Passant.Monday, August 10, 2009 3:50 PM -
For the example above, you ideal is works very well. However, I have a problem to use ananomous class the my current function:
Here is senranio : I have a object tyep Student and my function return an object type T
class Student {
public Student() { }
public string Name { get; set; }
public string SSN { get; set; }
public float GPA { get; set; }
}
T DbCtr.GetObject<T>(string sql )
Example :
Student studentA = dbCtrl.GetObject<Student> ( "Select * from Student where SSN='XXX-XX-XXXX');
Now I want to achive the same thing with ananomous class.
Regards,
JdangMonday, August 10, 2009 7:59 PM -
Why are you still persisting with using the generic type parameter?
Your code snippets do not indicate a need or a purpose for it.
Where or rather when is your anonymous class defined?
In order for it to be a generic type parameter, I think it needs to "Reflectable". If there is such a word.
Meaning if you can do Reflection on the type, then the generic method will not have any problems.
Mark the best replies as answers. "Fooling computers since 1971."Monday, August 10, 2009 8:04 PM -
You may also consider not using the anonymous type. The sole purpose of anonymous types is to make your life simple. If instead it's giving you a hard time, then just don't use them.
I'm not so sure about the "no need for generics". That method does give type safety compared to the non-generic version that would look something like this: object GetObject (Type objType, string sql).
Hope it helps,
Fernando.
I always try to Keep it Sharp & simple.- Proposed as answer by Michael Sun [MSFT]Microsoft employee Friday, August 14, 2009 5:12 AM
- Marked as answer by Michael Sun [MSFT]Microsoft employee Tuesday, August 18, 2009 1:25 AM
Monday, August 10, 2009 8:12 PM -
Sure this option will works but it required to modify existing codes. I may be able to overload this function to work with ananomoys type.
Regards,
JdangMonday, August 10, 2009 8:15 PM -
Sure this option will works but it required to modify existing codes. I may be able to overload this function to work with ananomoys type.
Regards,
Jdang
Are we talking about the same anonymous types here? I don't think so.
I am beginning to think Jdang means "random".
Mark the best replies as answers. "Fooling computers since 1971."Monday, August 10, 2009 8:23 PM -
Omitting the type argument from the generic function method call will only work if the compiler can deduce the type argument from the method arguments. That won't work if you pass a string.
Passing a fake argument to help won't work. You will have to create a real instance of T as the return value and that requires the new() constraint. Now passing the fake anonymous type doesn't work anymore since it doesn't have a public constructor.
You can't use a generic method to create an anonymous type object.
Hans Passant.- Proposed as answer by Michael Sun [MSFT]Microsoft employee Friday, August 14, 2009 5:12 AM
- Marked as answer by Michael Sun [MSFT]Microsoft employee Tuesday, August 18, 2009 1:25 AM
Monday, August 10, 2009 8:48 PM -
I understand the problem. May be the best option for me right now is to continue to create a class instead to ananomous object.
thanks,
JdangMonday, August 10, 2009 8:52 PM -
Hi Jdang,
I agree with nobugz that the compiler should first know the generic type information passed in. The SQL select string won’t tell the compiler the type information. What if we passed the T type into the generic method or extension method?
==================================================
public static T GetObject<T>(this T obj, string selectText)
==================================================We get the anonymous type object, its type, and the selectText, but I think we still cannot return the anonymous type object successfully. Your GetObject method reminds me some LINQ to SQL method like DataContext.ExecuteQuery<T>. The following method will throw some exception like the anonymous type does not define a parameterless constructor in order to be constructed during mapping.
==================================================
public static T GetObject<T>(this T obj, string selectText)
{
MyDataContext db = new MyDataContext();
return db.ExecuteQuery<T>(selectText).First();
}
==================================================
If we use .NET Reflector to check the implementation of the anonymous type, we find that they are realized by some internal sealed types with compiler-generated names. They have private readonly fields, public readonly properties, a public constructor with fields as parameters, overridden Equals, GetHashCode, and ToString methods. Because the names of the readonly fields are generated by the compiler, we cannot know the names in advance. In GetObject method, it seems that we can only access the readonly fields by calling the constructor to create new anonymous type object via Reflection.If Student object contains two properties, StudentID, and Name, then these codes may return the first row information inside the Student data table.
===================================================
var student = new { StudentID = 0, Name = "" };var newstudent = student.GetObject("SELECT * FROM [Student]");
public static class MyExtensionMethod
{
public static T GetObject<T>(this T obj, string selectText)
{
MyDataContext db = new MyDataContext();
var s = db.ExecuteQuery<Student>(selectText).First();
var constructor = obj.GetType().GetConstructor(new Type[] { typeof(int), typeof(string) });
return (T)constructor.Invoke(new object[] { s.StudentID, s.Name });
}
}
===================================================
However, I am afraid that such codes are totally away from our original design goal of anonymous type and your generic method with anonymous type. Hope my post can help you understand clearer.
Have a nice day!
Best Regards,
Lingzhi SunMSDN Subscriber Support in Forum
If you have any feedback on our support, please contact msdnmg@microsoft.com
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.- Proposed as answer by Michael Sun [MSFT]Microsoft employee Friday, August 14, 2009 5:13 AM
- Marked as answer by Michael Sun [MSFT]Microsoft employee Tuesday, August 18, 2009 1:25 AM
Tuesday, August 11, 2009 7:50 AM