如何将对象转换为其类型?
如何将对象(Object类型)转换为实际类型?
我需要做这样的事情
Myobject [i] += Myobject [j];
Myobject的类型是Object。 Myobject [i]和myobject [j]将始终属于同一类型。
Myobject [i] .Gettype()会给我类型…但是我如何将对象实际转换为该类型以执行’+’运算符
我假设为您的自定义类型定义了加法( +
)运算符(在此示例中为MyType
)。
如果是这样,您只需要转换分配的LHS和RHS。 这是必需的,因为两个操作数在编译时必须是已知类型才能选择正确的运算符重载。 这是静态语言所需要的,尽管动态语言(可能是C#4.0)可以解决这个问题。
((MyType)Myobject[i]) += (MyType)Myobject[j];
更新:
一些reflection魔法可以在C#2.0 / 3.0中解决这个问题(缺乏动态类型)。
public static object Add(object a, object b) { var type = a.GetType(); if (type != b.GetType()) throw new ArgumentException("Operands are not of the same type."); var op = type.GetMethod("op_Addition", BindingFlags.Static | BindingFlags.Public); return op.Invoke(null, new object[] { a, b }); }
请注意,这仅适用于非基本类型 。 对于诸如int
, float
等原始类型,您需要在手动转换操作数并应用加法运算符的类型上添加switch语句。 这是因为操作符重载实际上并不是为原始类型定义的,而是内置于CLR中。
无论如何,希望能解决你的问题。
类型是在编译时知道的吗?
除了已知的固定类型之外,C#不支持运算符(直到C#4.0)。
您可以通过一些技巧使用generics运算符 – 就像这样 。 让我知道generics是否是一个因素(我可以详细谈论这个……)
在4.0中,您可以使用:
dynamic x = MyObject[i]; x += MyObject[j]; MyObject[i] = x;
dynamic
的使用会导致很多魔法发生;-p
除了这两个场景之外,您需要在编译时知道它们的类型,或者做很多工作。
如果Myobject
是一个arrays那么
Myobject [i] += Myobject [j];
只要为类型定义了+
运算符就应该工作。
由于Myobject
属于object类型,因此会失败并显示错误:
运算符’+’不能应用于’对象’和’对象’类型的操作数
要在运行时获取类型(一个人为的例子):
double a = 1.0; double b = 2.0; object a1 = a; object b1 = b; Type ta = a1.GetType(); Type tb = b1.GetType();
ta
和tb
设置为“Double”。
更新:
提前警告 – 我要提出的建议非常笨拙(至少可以说)
如果您的类型数量有限且类型保证相同。 如果是这样,您可以执行以下操作:
Type test = Myobject[i].GetType(); if (test.Equals(typeof(double))) { (double)Myobject[i] += (double)Myobject[j]; }
等等。
如果类型不一样,那就有点复杂了。
如果你有一个未知数量的类型,那么你需要等待C#4。
或者你可以用Noldorin建议的反思来做。
最好避免装箱和拆箱并使用直接类型。 我不知道你的所有背景,但也许最好将数组切换到实际类型,或使用通用列表?
MyType[] array = new MyType[x];
要么
List list = new List ();
我建议使用swicth语句,因为类型将是数字类型。 在每个分支上,您可以将数字转换为临时变量并执行以下操作:
switch (Myobjetc[j].GetType()) { case typeof(short): break; case typeof(int): int a, b = 0; a = (int)Myobjet[i]; b = (int)Myobject[j]; a += b; break; case typeof(long): break; case typeof(decimal): break; case typeof(double): break; case typeof(float): break; default: break; }
对于不需要switch语句的原始类型的更好的解决方案是这样的:(VB.Net)
Private Shared AddT As Func(Of T, T, T) If AddT = Nothing Then Dim paramX As Expressions.ParameterExpression = Expressions.Expression.Parameter(GetType(T), "x") Dim paramY As Expressions.ParameterExpression = Expressions.Expression.Parameter(GetType(T), "y") Dim body As Expressions.BinaryExpression = Expressions.Expression.AddChecked(paramX, paramY) Matrix(Of T).AddT = Expressions.Expression.Lambda(Of Func(Of T, T, T))(body, paramX, paramY).Compile End If Private a as MyType Private b as MyType AddT(a,b) 'instead of a+b
乘法,除法等的解决方案是类似的。 希望将上述内容转换为C#不会太痛苦! 重要的是共享(静态)AddT,因为每次重新编译lambda表达式都会浪费时钟周期。 太糟糕.Net没有“MyType实现{+, – ,*,etc}”!