如何在 C# 中在运行时检查类型的可分配性? [英] How to check assignability of types at runtime in C#?
问题描述
Type
类有一个几乎可以工作的方法 IsAssignableFrom()
.不幸的是,它仅在两种类型相同或第一种类型在第二种类型的层次结构中时才返回 true.它说 decimal
不能从 int
分配,但我想要一种方法来表明 decimal
可以从 分配int
s,但 int
s 并不总是可以从 decimal
s 赋值.编译器知道这一点,但我需要在运行时弄清楚这一点.
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 decimal
s are assignable from int
s, but int
s are not always assignable from decimal
s. 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
已经检查的内容.(这也包括允许的装箱操作,例如int
到object
或DateTime
到ValueType
.)Class hierarchy, interface implementation, covariance and contravariance. This is what
.IsAssignableFrom
already checks for. (This also includes permissible boxing operations, e.g.int
toobject
orDateTime
toValueType
.)
用户定义的隐式转换.这就是所有其他答案所指的内容.您可以通过反射检索这些,例如,从
int
到decimal
的隐式转换是一个如下所示的静态方法: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
todecimal
is a static method that looks like this:System.Decimal op_Implicit(Int32)
您只需要检查两个相关类型(在本例中为
Int32
和Decimal
);如果转换不在那些中,则它不存在.You only need to check the two relevant types (in this case,
Int32
andDecimal
); if the conversion is not in those, then it doesn’t exist.在 C# 语言规范. 不幸的是,反射没有显示这些.您必须在规范中找到它们并手动将可分配性规则复制到您的代码中.这包括数字转换,例如
int
到long
以及float
到double
、指针转换、可空转换 (int
code> 到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
tolong
as well asfloat
todouble
, pointer conversions, nullable conversions (int
toint?
), and lifted conversions.此外,用户定义的隐式转换可以与内置的隐式转换链接.例如,如果存在从
int
到某种类型T
的用户定义的隐式转换,那么它也兼作从short
到 <代码>T.类似地,T
到short
可以作为T
到int
的两倍.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 typeT
, then it also doubles as a conversion fromshort
toT
. Similarly,T
toshort
doubles asT
toint
.这篇关于如何在 C# 中在运行时检查类型的可分配性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!