【问题标题】:cast object with a Type variable使用 Type 变量强制转换对象
【发布时间】:2012-02-18 19:08:06
【问题描述】:

当然,以下内容不起作用。有没有可能的方法,和这个很相似?

Type newObjectType = typeof(MyClass);

var newObject = givenObject as newObjectType;

【问题讨论】:

  • 你研究过泛型吗? MyClass<T>,然后是var newObject = givenObject as T
  • 我已经为通用对象使用了泛型。但是还有一些特殊的需要显式转换 - 除了通用的。
  • 特殊对象是什么意思?
  • 对象可能是错误的词。我们有很多自定义数据字段(字符串、整数、日期时间……)。但也有一些我们无法用泛型处理,因为处理相对于整数和字符串的处理来说还不够。
  • 目的是什么?是否要将给定对象视为 MyClass?如果是这样,为什么不直接var newObject = givenObject as MyClass。如果不是,那么 newObject 的类型是什么?您将如何访问其成员?我错过了什么?如果您在编译时知道类型,那么您应该能够转换为该类型。如果您在编译时不知道类型,您打算如何访问该对象?

标签: c# types


【解决方案1】:

newObjectTypeType 类(包含有关类型的元数据)的实例,而不是类型 本身。

这应该可以工作

var newObject = givenObject as MyClass;

var newObject = (MyClass) givenObject;

强制转换为类型的实例确实没有意义,因为编译时必须知道变量类型应该是什么,而类型的实例是运行时概念.

var 可以工作的唯一方法是在编译时知道变量的类型。


更新

铸造通常是一个编译时的概念,即你必须在编译时知道类型。

类型转换是一个运行时概念。


更新 2

如果需要使用该类型的变量进行调用,而编译时不知道该类型,可以使用反射:使用MethodInfo on的Invoke方法类型实例。

object myString = "Ali";
Type type = myString.GetType();
MethodInfo methodInfo = type.GetMethods().Where(m=>m.Name == "ToUpper").First();
object invoked = methodInfo.Invoke(myString, null);
Console.WriteLine(invoked);
Console.ReadLine();

【讨论】:

  • 我认为 OP 想要在运行时进行某种动态转换。
  • 那是另一个问题。还要投来做什么? 强制转换是一个编译时概念。
  • "newObjectType 是类型的实例而不是类型本身" 当你说“类型”时,你指的是MyClass吗?因为那根本不是真的。
  • 哦,我忽略了我在 .NET 中听说过的类型安全问题 :-D 我试过 givenField = givenField as NewType,我想知道这个 givenField 仍然缺少刚刚给出的字段之后在NewType。但你的回答给了我线索。对不起。^^
  • 此答案需要编辑或删除。显示如何调用 MethodInfo.Invoke 仍然无法回答问题。
【解决方案2】:

您可以使用 IsAssignableFrom 检查类型是否存在

if(givenObject.GetType().IsAssignableFrom(newObjectType))

但是你不能在这里使用 var 因为类型在编译时是未知的。

【讨论】:

    【解决方案3】:

    也许你可以使用泛型解决这个问题。

    public void CastToMyType<T>(object givenObject) where T : class
    {
       var newObject = givenObject as T;
    }
    

    【讨论】:

    • 否:类型参数“T”不能与“as”运算符一起使用,因为它没有类类型约束,也没有“类”约束
    • public void CastToMyType(object givenObject) where T : class { var newObject = givenObject as T; }
    • 这样,当您想使用在运行时检索到的类型调用CastToMyType() 时,您仍然会遇到同样的问题。您实际上是在尝试这样做:CastToMyType&lt;someVar.GetType()&gt;() 这是不可能的。
    【解决方案4】:

    我最近有一个案例,我需要生成一些代码,例如Tomislav's answer。不幸的是,在世代期间,类型 T 是未知的。但是,包含该类型实例的变量是已知的。针对该问题的solution肮脏的hack/解决方法是:

    public void CastToMyType<T>(T hackToInferNeededType, object givenObject) where T : class
    {
       var newObject = givenObject as T;
    }
    

    那么这可以被CastToMyType(instanceOfNeededType, givenObject)调用,让编译器推断T。

    【讨论】:

      【解决方案5】:

      您可以使用 Convert.ChangeType。根据msdn,它

      返回一个指定类型的对象,其值等价于 指定对象。

      你可以试试下面的代码:

      Type newObjectType = typeof(MyClass);
      
      var newObject = Convert.ChangeType(givenObject, newObjectType);
      

      【讨论】:

      • 除了newObjectType必须实现IConvertible接口。否则,它会抛出 System.InvalidCastException
      • 由于这个返回对象,它就不能被用作某个方法的输入。这让我们回到了如何动态转换的问题。
      猜你喜欢
      • 2014-02-16
      • 2018-11-24
      • 2012-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-16
      相关资源
      最近更新 更多