如何在 C# 中在运行时检查类型的可分配性? [英] How to check assignability of types at runtime in C#?

查看:29
本文介绍了如何在 C# 中在运行时检查类型的可分配性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Type 类有一个几乎可以工作的方法 IsAssignableFrom().不幸的是,它仅在两种类型相同或第一种类型在第二种类型的层次结构中时才返回 true.它说 decimal 不能从 int 分配,但我想要一种方法来表明 decimal 可以从 分配ints,但 ints 并不总是可以从 decimals 赋值.编译器知道这一点,但我需要在运行时弄清楚这一点.

The Type class has a method IsAssignableFrom() that almost works. Unfortunately it only returns true if the two types are the same or the first is in the hierarchy of the second. It says that decimal is not assignable from int, but I'd like a method that would indicate that decimals are assignable from ints, but ints are not always assignable from decimals. The compiler knows this but I need to figure this out at runtime.

这是一个扩展方法的测试.

Here's a test for an extension method.

[Test]
public void DecimalsShouldReallyBeAssignableFromInts()
{
    Assert.IsTrue(typeof(decimal).IsReallyAssignableFrom(typeof(int)));
    Assert.IsFalse(typeof(int).IsReallyAssignableFrom(typeof(decimal)));
}

有没有一种方法可以实现 IsReallyAssignableFrom() ,它既可以像 IsAssignableFrom() 一样工作,又可以通过上面的测试用例?

Is there a way to implement IsReallyAssignableFrom() that would work like IsAssignableFrom() but also passes the test case above?

谢谢!

这基本上就是它的使用方式.这个例子不适合我编译,所以我必须将 Number 设置为 0(而不是 0.0M).

This is basically the way it would be used. This example does not compile for me, so I had to set Number to be 0 (instead of 0.0M).

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter)]
public class MyAttribute : Attribute
{
    public object Default { get; set; }
}

public class MyClass
{
    public MyClass([MyAttribute(Default= 0.0M)] decimal number)
    {
        Console.WriteLine(number);
    }
}

我收到此错误:

错误 4 属性参数必须是属性参数类型的常量表达式、typeof 表达式或数组创建表达式

Error 4 An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

推荐答案

实际上有三种方式可以将一个类型分配"给另一个类型,就像您正在寻找的那样.

There are actually three ways that a type can be "assignable" to another in the sense that you are looking for.

>

  • 类层次结构、接口实现、协变和逆变. 这是 .IsAssignableFrom 已经检查的内容.(这也包括允许的装箱操作,例如 intobjectDateTimeValueType.)

    • Class hierarchy, interface implementation, covariance and contravariance. This is what .IsAssignableFrom already checks for. (This also includes permissible boxing operations, e.g. int to object or DateTime to ValueType.)

    用户定义的隐式转换.这就是所有其他答案所指的内容.您可以通过反射检索这些,例如,从 intdecimal 的隐式转换是一个如下所示的静态方法:

    User-defined implicit conversions. This is what all the other answers are referring to. You can retrieve these via Reflection, for example the implicit conversion from int to decimal is a static method that looks like this:

    System.Decimal op_Implicit(Int32)
    

    您只需要检查两个相关类型(在本例中为Int32Decimal);如果转换不在那些中,则它不存在.

    You only need to check the two relevant types (in this case, Int32 and Decimal); if the conversion is not in those, then it doesn’t exist.

    C# 语言规范. 不幸的是,反射没有显示这些.您必须在规范中找到它们并手动将可分配性规则复制到您的代码中.这包括数字转换,例如intlong 以及 floatdouble、指针转换、可空转换 (intcode> 到 int?) 和 提升转化率.

    Built-in implicit conversions which are defined in the C# language specification. Unfortunately Reflection doesn’t show these. You will have to find them in the specification and copy the assignability rules into your code manually. This includes numeric conversions, e.g. int to long as well as float to double, pointer conversions, nullable conversions (int to int?), and lifted conversions.

    此外,用户定义的隐式转换可以与内置的隐式转换链接.例如,如果存在从 int 到某种类型 T 的用户定义的隐式转换,那么它也兼作从 short 到 <代码>T.类似地,Tshort 可以作为 Tint 的两倍.

    Furthermore, a user-defined implicit conversion can be chained with a built-in implicit conversion. For example, if a user-defined implicit conversion exists from int to some type T, then it also doubles as a conversion from short to T. Similarly, T to short doubles as T to int.

    这篇关于如何在 C# 中在运行时检查类型的可分配性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆