-1

maybe I'm not clever enough, but...

I have a freshly created anonymous object and wanna cast it to a special class.


I tried something like:

  • () convert: SomeClass casted = (ClassName) obj
  • as type: SomeClass casted = obj as ClassName

The last idea I found online was to cast via each property: https://dotnetfiddle.net/bU8gwE (by method: CastTo<T>(object))

But nothing worked. :(


Here is my object:

var test = new { FieldOne = "test2", FieldTwo = 2 };

And here is my type, it's an own class:

public class SomeClass
{
    public string FieldOne;
    public int FieldTwo;
}

So how to cast obj in type SomeClass?

I'm happy for every advise.

Froschkoenig84
  • 566
  • 4
  • 13
  • 1
    You can't cast an anonymous object to a different class. It already has a class, just one you didn't define. The best you can do is manually copy the properties over to a different class. – Kirk Woll Jun 16 '22 at 17:35
  • 1
    Just because two classes have identically named members, doesn't mean they are the same and can be casted into each other. Your options are to either create the correct type from the beginning or to create a copy of the object with the correct type. You can only cast an object to one of its parent classes or implemented interfaces. – Christof Wollenhaupt Jun 16 '22 at 17:37
  • What you are talking about is called duck typing and that isn't supported by C#. You need to map the object manually. – DavidG Jun 16 '22 at 17:38
  • additionally, *properties* wont automagically map to *fields* – Ňɏssa Pøngjǣrdenlarp Jun 16 '22 at 17:40
  • The problem is I can't create a simple instance, I would do, but I get a anonymous object by an api request. - And that was just a sample I found online. https://www.codeproject.com/Articles/38635/Converting-anonymous-types-to-any-type and https://mitch.codes/casting-object-to-anonymous-types-in-csharp/ – Froschkoenig84 Jun 16 '22 at 18:34

3 Answers3

0

First and primarily, a general advice: do not use empty catch clauses in your try-catch constructs (with the exception of so-called vexing exceptions, but i digress). If you try your hardest to ignore and discard any exception your code throws unseen, you will have a very hard time knowing what's going wrong with your code.

If you were to print out any caught exception instead of silently discarding it, the exception would tell you what is going wrong with your code (i.e., what needs to be fixed in your code).

Anyways, with this line:

tmp.GetType().GetProperty(pi.Name).SetValue(...)

you are trying to obtain a property info from your CodeRecord class (tmp is an instance of CodeRecord). Now, look at your CodeRecord class. There are no properties defined in CodeRecord, only fields. If you want to populate the fields in CodeRecord through reflection, you will need to get a FieldInfo and not a PropertyInfo:

tmp.GetType().GetField(pi.Name).SetValue(tmp, pi.GetValue(obj, null));

Some unrelated observation:

What the heck is Activator.CreateInstance(Type.GetType(typeof(T).ToString()))??? You have the type object for T via typeof(T). You then get its name string. With its name string you try to find the type object of T again which you already had with typeof(T). I don't know what that is, but me thinks you need some sleep ;-P You could just have used Activator.CreateInstance(typeof(T)). Well, hold on, i take that back, you could just have used Activator.CreateInstance<T>().

0

I got it: https://dotnetfiddle.net/nvxchR

And it was not FieldInfo, it was PropertyInfo, exactly as I said.

var tmp = new CodeRecord();
(obj.GetType()).GetProperties().ToList().ForEach(prop =>
    tmp.GetType().GetField(prop.Name).SetValue(tmp, prop.GetValue(obj, null)));
return tmp;

Okay, the reflections are expensive, so I first try to ask if type is right and only if not I use the for each sample above.

But so it's possible to cast an anonymous object in a class (type).

Froschkoenig84
  • 566
  • 4
  • 13
0

Maybe the situation is more "dynamic" than I realize, but why not just:

SomeClass casted = new SomeClass { FieldOne = test.FieldOne, FieldTwo = test.FieldTwo, };
Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
  • Exactly. Because the dynamic members of the class (or of the a-object). In the end this should be a small caching object for code-segments of a script parser. But you're right. Initially, I'll keep it dynamic and flexible. Later, when I've actually integrated most of the possible code sequences of my scripting language, I'll make the whole class static and the field assignment just as direct. But there may be hundreds of fields and I rarely need them all. – Froschkoenig84 Jun 16 '22 at 21:44
  • PS: The fields are not strings or integers either, but get special code-parser types with individual properties and methods. This simple example was just for demonstration. – Froschkoenig84 Jun 16 '22 at 21:46