简体   繁体   English

如何将对象转换为其类型?

[英]How to cast an object into its type?

How to cast an object (of type Object) into its real type? 如何将对象(Object类型)转换为实际类型?

I need to do some thing like this 我需要做这样的事情

Myobject [i] += Myobject [j];

Myobject's type is Object. Myobject的类型是Object。 Myobject [i] and myobject [j] will always be of same type. Myobject [i]和myobject [j]将始终属于同一类型。

Myobject[i].Gettype() would give me the type... but how would i actually cast the object into that type to perform the '+' operator Myobject [i] .Gettype()会给我类型...但是我如何将对象实际转换为该类型以执行'+'运算符

I'm assuming the addition ( + ) operator is defined for your custom type ( MyType in this example). 我假设为您的自定义类型定义了加法( + )运算符(在此示例中为MyType )。

If so, you simply need to cast the LHS and RHS of the assignment. 如果是这样,您只需要转换分配的LHS和RHS。 This is required because both operands must be of known types at compile-time in order to choose the correct operator overload. 这是必需的,因为两个操作数在编译时必须是已知类型才能选择正确的运算符重载。 This is something required by static languages, though dynamic languages (possibly C# 4.0) may resolve this. 这是静态语言所需要的,尽管动态语言(可能是C#4.0)可以解决这个问题。

((MyType)Myobject[i]) += (MyType)Myobject[j];

Update: 更新:

Some reflection magic can get around this problem in C# 2.0/3.0 (with lack of dynamic typing). 一些反射魔法可以在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 });
}

Note that this only works for non-primitive types . 请注意,这仅适用于非基本类型 For primitive types such as int , float , etc., you would need to add a switch statement on the type that manually cast the operands and applied the addition operator. 对于诸如intfloat等原始类型,您需要在手动转换操作数并应用加法运算符的类型上添加switch语句。 This is because operator overloads aren't actually defined for primitive types, but rather built in to the CLR. 这是因为操作符重载实际上并不是为原始类型定义的,而是内置于CLR中。

Anyway, hope that solves your problem. 无论如何,希望能解决你的问题。

Is the type known at compile time? 类型是在编译时知道的吗?

C# does not (until C# 4.0) support operators on anything except known, fixed types. 除了已知的固定类型之外,C#不支持运算符(直到C#4.0)。

You can use operators with generics via a few tricks - like so . 您可以通过一些技巧使用泛型运算符 - 就像这样 Let me know if generics are a factor here (I can talk at length on this...) 让我知道泛型是否是一个因素(我可以详细谈论......)

In 4.0, you can use: 在4.0中,您可以使用:

dynamic x = MyObject[i];
x += MyObject[j];
MyObject[i] = x;

The use of dynamic causes a lot of magic to happen ;-p dynamic的使用会导致很多魔法发生;-p

Other than those two scenarios, you need to know their type at compile-time, or do a lot of work. 除了这两个场景之外,您需要在编译时知道它们的类型,或者做很多工作。

If Myobject is an array then 如果Myobject是一个阵列那么

Myobject [i] += Myobject [j];

should work as long as the + operator has been defined for the type. 只要为类型定义了+运算符就应该工作。

As Myobject is of type object this will fail with the error: 由于Myobject属于object类型,因此会失败并显示错误:

Operator '+' cannot be applied to operands of type 'object' and 'object' 运算符'+'不能应用于'object'和'object'类型的操作数

To get the type at runtime (a contrived example): 要在运行时获取类型(一个人为的例子):

double a = 1.0;
double b = 2.0;

object a1 = a;
object b1 = b;

Type ta = a1.GetType();
Type tb = b1.GetType();

ta and tb are set to "Double". tatb设置为“Double”。

UPDATE: 更新:

A word of warning in advance - what I am about to suggest is very ungainly (to say the least) 提前发出警告 - 我要暗示的是非常笨拙(至少可以说)

If you have a finite number of types and are the types guaranteed to be the same. 如果您的类型数量有限且类型保证相同。 If so you could do the following: 如果是这样,您可以执行以下操作:

Type test = Myobject[i].GetType();
if (test.Equals(typeof(double)))
{
   (double)Myobject[i] += (double)Myobject[j];
}

and so on. 等等。

If the types aren't the same then it's a bit more complicated. 如果类型不一样,那就有点复杂了。

If you have got an unknown number of types then you'll need to wait for C# 4. 如果你有一个未知数量的类型,那么你需要等待C#4。

Or you could do with reflection as Noldorin suggests. 或者你可以用Noldorin建议的反思来做。

It is always better to avoid boxing and unboxing and use direct types. 最好避免装箱和拆箱并使用直接类型。 I do not know all your background, but maybe it is better to switch array to real type, or use generic list? 我不知道你的所有背景,但也许最好将数组切换到实际类型,或使用通用列表?

MyType[] array = new MyType[x];

or 要么

List<MyType> list = new List<MyType>();

I'll suggest using a swicth statement, as the type would be a numeric one. 我建议使用swicth语句,因为类型将是数字类型。 On each branch, you could cast your numbers to temp variables and perform the operation like: 在每个分支上,您可以将数字转换为临时变量并执行以下操作:

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;
    }

A better solution for primitive types that doesn't require a switch statement is like this: (VB.Net) 对于不需要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

Solutions for multiply, divide, etc, are similar. 乘法,除法等的解决方案是类似的。 Hopefully converting the above to C# won't be too painful! 希望将上述内容转换为C#不会太痛苦! It is important that AddT is shared (static) because recompiling the lambda expression each time will waste clock cycles. 重要的是AddT是共享的(静态的),因为每次重新编译lambda表达式都会浪费时钟周期。 Too bad .Net doesn't have a "MyType implements {+,-,*,etc}"! 太糟糕.Net没有“MyType实现{+, - ,*,etc}”!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM