C#.NET 创建一个简单的匿名对象并将其转换为类类型

c#.net create a simple anonymous object and convert it to class type

提问人:Froschkoenig84 提问时间:6/17/2022 最后编辑:Froschkoenig84 更新时间:6/17/2022 访问量:642

问:

也许我不够聪明,但是......

我有一个新创建的匿名对象,并想将其转换为一个特殊的类。


我尝试了类似的东西:

  • () 转换:SomeClass casted = (ClassName) obj
  • 作为类型:SomeClass casted = obj as ClassName

我在网上找到的最后一个想法是通过每个属性进行强制转换:https://dotnetfiddle.net/bU8gwE(通过方法:CastTo<T>(object)

但没有任何效果。:(


这是我的对象:

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

这是我的类型,它是一个自己的类:

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

那么如何铸造字体呢?objSomeClass

我很高兴每一个建议。

C# .NET 强制 类型转换 匿名对象

评论

1赞 Kirk Woll 6/17/2022
不能将匿名对象强制转换为其他类。它已经有一个类,只是一个你没有定义的类。最好的办法是手动将属性复制到其他类。
1赞 Christof Wollenhaupt 6/17/2022
仅仅因为两个类具有相同名称的成员,并不意味着它们是相同的,可以相互强制转换。您可以选择从头开始创建正确的类型,或者创建具有正确类型的对象副本。只能将对象强制转换为其父类或已实现的接口之一。
0赞 DavidG 6/17/2022
你所说的称为鸭子类型,C#不支持它。您需要手动映射对象。
0赞 Ňɏssa Pøngjǣrdenlarp 6/17/2022
此外,属性不会自动映射到字段
0赞 Froschkoenig84 6/17/2022
问题是我无法创建一个简单的实例,我会这样做,但我通过 api 请求获得了一个匿名对象。- 这只是我在网上找到的一个样本。codeproject.com/Articles/38635/......mitch.codes/casting-object-to-anonymous-types-in-csharp

答:

0赞 DrunkenCoder 6/17/2022 #1

首先,也是最主要的,一个一般的建议:不要在你的 - 结构中使用空的 catch 子句(除了所谓的烦恼异常,但我离题了)。如果你尽最大努力忽略和丢弃你的代码抛出的任何看不见的异常,你将很难知道你的代码出了什么问题。trycatch

如果您要打印出任何捕获的异常,而不是静默地丢弃它,则异常会告诉您代码出了什么问题(即,代码中需要修复什么)。

无论如何,用这一行:

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

您正在尝试从 CodeRecord 类(tmpCodeRecord 的实例)获取属性信息。现在,看看你的 CodeRecord 类。CodeRecord 中没有定义任何属性,只有字段。如果要通过反射填充 CodeRecord 中的字段,则需要获取 a 而不是 :FieldInfoPropertyInfo

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

一些不相关的观察结果:

这到底是怎么回事???您有 T 的类型对象,通过 。然后,您将获得其名称字符串。使用其名称字符串,您可以尝试再次找到 T 的类型对象,该对象已使用 .我不知道那是什么,但我认为你需要一些睡眠;-P你可以只用.好吧,等等,我把它收回来,你可以用.Activator.CreateInstance(Type.GetType(typeof(T).ToString()))typeof(T)typeof(T)Activator.CreateInstance(typeof(T))Activator.CreateInstance<T>()

1赞 Froschkoenig84 6/17/2022 #2

我明白了:https://dotnetfiddle.net/nvxchR

它不是 FieldInfo,而是 PropertyInfo,正如我所说。

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

好吧,反射很昂贵,所以我首先尝试询问类型是否正确,只有在不正确的情况下,我才会使用上面的每个样本。

但是,可以在类(类型)中强制转换匿名对象。

0赞 Jeppe Stig Nielsen 6/17/2022 #3

也许情况比我意识到的更“动态”,但为什么不只是:

SomeClass casted = new SomeClass { FieldOne = test.FieldOne, FieldTwo = test.FieldTwo, };

评论

0赞 Froschkoenig84 6/17/2022
完全。因为类(或 a-object)的动态成员。最后,这应该是脚本解析器代码段的一个小缓存对象。但你是对的。最初,我将保持它的动态性和灵活性。稍后,当我实际集成了我的脚本语言的大多数可能的代码序列时,我将使整个类成为静态的,并使字段分配同样直接。但是可能有数百个字段,我很少需要它们。
0赞 Froschkoenig84 6/17/2022
PS:这些字段也不是字符串或整数,而是获得具有单独属性和方法的特殊代码解析器类型。这个简单的例子只是为了演示。