本文整理汇总了C#中Microsoft.CSharp.RuntimeBinder.Semantics.CType.AsArrayType方法的典型用法代码示例。如果您正苦于以下问题:C# CType.AsArrayType方法的具体用法?C# CType.AsArrayType怎么用?C# CType.AsArrayType使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Microsoft.CSharp.RuntimeBinder.Semantics.CType
的用法示例。
在下文中一共展示了CType.AsArrayType方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: UpperBoundArrayInference
////////////////////////////////////////////////////////////////////////////////
private bool UpperBoundArrayInference(CType pSource, CType pDest)
{
// SPEC: Otherwise, if V is an array CType Ve[...] and U is an array
// SPEC: CType Ue[...] of the same rank, or if V is a one-dimensional array
// SPEC: CType Ve[] and U is one of IEnumerable<Ue>, ICollection<Ue>,
// SPEC: IList<Ue>, IReadOnlyCollection<Ue> or IReadOnlyList<Ue> then
// SPEC: if Ue is known to be a reference CType then an upper-bound inference
// SPEC: from Ue to Ve is made.
// SPEC: otherwise an exact inference from Ue to Ve is made.
if (!pDest.IsArrayType())
{
return false;
}
ArrayType pArrayDest = pDest.AsArrayType();
CType pElementDest = pArrayDest.GetElementType();
CType pElementSource = null;
if (pSource.IsArrayType())
{
ArrayType pArraySource = pSource.AsArrayType();
if (pArrayDest.rank != pArraySource.rank)
{
return false;
}
pElementSource = pArraySource.GetElementType();
}
else if (pSource.isPredefType(PredefinedType.PT_G_IENUMERABLE) ||
pSource.isPredefType(PredefinedType.PT_G_ICOLLECTION) ||
pSource.isPredefType(PredefinedType.PT_G_ILIST) ||
pSource.isPredefType(PredefinedType.PT_G_IREADONLYLIST) ||
pSource.isPredefType(PredefinedType.PT_G_IREADONLYCOLLECTION))
{
if (pArrayDest.rank != 1)
{
return false;
}
AggregateType pAggregateSource = pSource.AsAggregateType();
pElementSource = pAggregateSource.GetTypeArgsThis().Item(0);
}
else
{
return false;
}
if (pElementSource.IsRefType())
{
UpperBoundInference(pElementSource, pElementDest);
}
else
{
ExactInference(pElementSource, pElementDest);
}
return true;
}
示例2: ExactArrayInference
////////////////////////////////////////////////////////////////////////////////
private bool ExactArrayInference(CType pSource, CType pDest)
{
// SPEC: Otherwise, if U is an array CType UE[...] and V is an array CType VE[...]
// SPEC: of the same rank then an exact inference from UE to VE is made.
if (!pSource.IsArrayType() || !pDest.IsArrayType())
{
return false;
}
ArrayType pArraySource = pSource.AsArrayType();
ArrayType pArrayDest = pDest.AsArrayType();
if (pArraySource.rank != pArrayDest.rank)
{
return false;
}
ExactInference(pArraySource.GetElementType(), pArrayDest.GetElementType());
return true;
}
示例3: LowerBoundArrayInference
////////////////////////////////////////////////////////////////////////////////
private bool LowerBoundArrayInference(CType pSource, CType pDest)
{
// SPEC: Otherwise, if U is an array CType Ue[...] and V is either an array
// SPEC: CType Ve[...] of the same rank, or if U is a one-dimensional array
// SPEC: CType Ue[] and V is one of IEnumerable<Ve>, ICollection<Ve>,
// SPEC: IList<Ve>, IReadOnlyCollection<Ve> or IReadOnlyList<Ve> then
// SPEC: if Ue is known to be a reference CType then a lower-bound inference
// SPEC: from Ue to Ve is made.
// SPEC: otherwise an exact inference from Ue to Ve is made.
// Consider the following:
//
// abstract class B<T> { public abstract M<U>(U u) : where U : T; }
// class D : B<int[]> {
// static void M<X>(X[] x) { }
// public override M<U>(U u) { M(u); } // should infer M<int>
// }
if (pSource.IsTypeParameterType())
{
pSource = pSource.AsTypeParameterType().GetEffectiveBaseClass();
}
if (!pSource.IsArrayType())
{
return false;
}
ArrayType pArraySource = pSource.AsArrayType();
CType pElementSource = pArraySource.GetElementType();
CType pElementDest = null;
if (pDest.IsArrayType())
{
ArrayType pArrayDest = pDest.AsArrayType();
if (pArrayDest.rank != pArraySource.rank)
{
return false;
}
pElementDest = pArrayDest.GetElementType();
}
else if (pDest.isPredefType(PredefinedType.PT_G_IENUMERABLE) ||
pDest.isPredefType(PredefinedType.PT_G_ICOLLECTION) ||
pDest.isPredefType(PredefinedType.PT_G_ILIST) ||
pDest.isPredefType(PredefinedType.PT_G_IREADONLYCOLLECTION) ||
pDest.isPredefType(PredefinedType.PT_G_IREADONLYLIST))
{
if (pArraySource.rank != 1)
{
return false;
}
AggregateType pAggregateDest = pDest.AsAggregateType();
pElementDest = pAggregateDest.GetTypeArgsThis().Item(0);
}
else
{
return false;
}
if (pElementSource.IsRefType())
{
LowerBoundInference(pElementSource, pElementDest);
}
else
{
ExactInference(pElementSource, pElementDest);
}
return true;
}
示例4: SubstEqualTypesCore
public bool SubstEqualTypesCore(CType typeDst, CType typeSrc, SubstContext pctx)
{
LRecurse: // Label used for "tail" recursion.
if (typeDst == typeSrc || typeDst.Equals(typeSrc))
{
return true;
}
switch (typeSrc.GetTypeKind())
{
default:
Debug.Assert(false, "Bad Symbol kind in SubstEqualTypesCore");
return false;
case TypeKind.TK_NullType:
case TypeKind.TK_VoidType:
case TypeKind.TK_OpenTypePlaceholderType:
// There should only be a single instance of these.
Debug.Assert(typeDst.GetTypeKind() != typeSrc.GetTypeKind());
return false;
case TypeKind.TK_ArrayType:
if (typeDst.GetTypeKind() != TypeKind.TK_ArrayType || typeDst.AsArrayType().rank != typeSrc.AsArrayType().rank)
return false;
goto LCheckBases;
case TypeKind.TK_ParameterModifierType:
if (typeDst.GetTypeKind() != TypeKind.TK_ParameterModifierType ||
((pctx.grfst & SubstTypeFlags.NoRefOutDifference) == 0 &&
typeDst.AsParameterModifierType().isOut != typeSrc.AsParameterModifierType().isOut))
return false;
goto LCheckBases;
case TypeKind.TK_PointerType:
case TypeKind.TK_NullableType:
if (typeDst.GetTypeKind() != typeSrc.GetTypeKind())
return false;
LCheckBases:
typeSrc = typeSrc.GetBaseOrParameterOrElementType();
typeDst = typeDst.GetBaseOrParameterOrElementType();
goto LRecurse;
case TypeKind.TK_AggregateType:
if (typeDst.GetTypeKind() != TypeKind.TK_AggregateType)
return false;
{ // BLOCK
AggregateType atsSrc = typeSrc.AsAggregateType();
AggregateType atsDst = typeDst.AsAggregateType();
if (atsSrc.getAggregate() != atsDst.getAggregate())
return false;
Debug.Assert(atsSrc.GetTypeArgsAll().Size == atsDst.GetTypeArgsAll().Size);
// All the args must unify.
for (int i = 0; i < atsSrc.GetTypeArgsAll().Size; i++)
{
if (!SubstEqualTypesCore(atsDst.GetTypeArgsAll().Item(i), atsSrc.GetTypeArgsAll().Item(i), pctx))
return false;
}
}
return true;
case TypeKind.TK_ErrorType:
if (!typeDst.IsErrorType() || !typeSrc.AsErrorType().HasParent() || !typeDst.AsErrorType().HasParent())
return false;
{
ErrorType errSrc = typeSrc.AsErrorType();
ErrorType errDst = typeDst.AsErrorType();
Debug.Assert(errSrc.nameText != null && errSrc.typeArgs != null);
Debug.Assert(errDst.nameText != null && errDst.typeArgs != null);
if (errSrc.nameText != errDst.nameText || errSrc.typeArgs.Size != errDst.typeArgs.Size)
return false;
if (errSrc.HasTypeParent() != errDst.HasTypeParent())
{
return false;
}
if (errSrc.HasTypeParent())
{
if (errSrc.GetTypeParent() != errDst.GetTypeParent())
{
return false;
}
if (!SubstEqualTypesCore(errDst.GetTypeParent(), errSrc.GetTypeParent(), pctx))
{
return false;
}
}
else
{
if (errSrc.GetNSParent() != errDst.GetNSParent())
{
return false;
}
}
// All the args must unify.
//.........这里部分代码省略.........
示例5: CalculateAssociatedSystemType
private static Type CalculateAssociatedSystemType(CType src)
{
Type result = null;
switch (src.GetTypeKind())
{
case TypeKind.TK_ArrayType:
ArrayType a = src.AsArrayType();
Type elementType = a.GetElementType().AssociatedSystemType;
if (a.rank == 1)
{
result = elementType.MakeArrayType();
}
else
{
result = elementType.MakeArrayType(a.rank);
}
break;
case TypeKind.TK_NullableType:
NullableType n = src.AsNullableType();
Type underlyingType = n.GetUnderlyingType().AssociatedSystemType;
result = typeof(Nullable<>).MakeGenericType(underlyingType);
break;
case TypeKind.TK_PointerType:
PointerType p = src.AsPointerType();
Type referentType = p.GetReferentType().AssociatedSystemType;
result = referentType.MakePointerType();
break;
case TypeKind.TK_ParameterModifierType:
ParameterModifierType r = src.AsParameterModifierType();
Type parameterType = r.GetParameterType().AssociatedSystemType;
result = parameterType.MakeByRefType();
break;
case TypeKind.TK_AggregateType:
result = CalculateAssociatedSystemTypeForAggregate(src.AsAggregateType());
break;
case TypeKind.TK_TypeParameterType:
TypeParameterType t = src.AsTypeParameterType();
if (t.IsMethodTypeParameter())
{
MethodInfo meth = t.GetOwningSymbol().AsMethodSymbol().AssociatedMemberInfo as MethodInfo;
result = meth.GetGenericArguments()[t.GetIndexInOwnParameters()];
}
else
{
Type parentType = t.GetOwningSymbol().AsAggregateSymbol().AssociatedSystemType;
result = parentType.GetTypeInfo().GenericTypeParameters[t.GetIndexInOwnParameters()];
}
break;
case TypeKind.TK_ArgumentListType:
case TypeKind.TK_BoundLambdaType:
case TypeKind.TK_ErrorType:
case TypeKind.TK_MethodGroupType:
case TypeKind.TK_NaturalIntegerType:
case TypeKind.TK_NullType:
case TypeKind.TK_OpenTypePlaceholderType:
case TypeKind.TK_UnboundLambdaType:
case TypeKind.TK_VoidType:
default:
break;
}
Debug.Assert(result != null || src.GetTypeKind() == TypeKind.TK_AggregateType);
return result;
}
示例6: SubstTypeCore
private CType SubstTypeCore(CType type, SubstContext pctx)
{
CType typeSrc;
CType typeDst;
switch (type.GetTypeKind())
{
default:
Debug.Assert(false);
return type;
case TypeKind.TK_NullType:
case TypeKind.TK_VoidType:
case TypeKind.TK_OpenTypePlaceholderType:
case TypeKind.TK_MethodGroupType:
case TypeKind.TK_BoundLambdaType:
case TypeKind.TK_UnboundLambdaType:
case TypeKind.TK_NaturalIntegerType:
case TypeKind.TK_ArgumentListType:
return type;
case TypeKind.TK_ParameterModifierType:
typeDst = SubstTypeCore(typeSrc = type.AsParameterModifierType().GetParameterType(), pctx);
return (typeDst == typeSrc) ? type : GetParameterModifier(typeDst, type.AsParameterModifierType().isOut);
case TypeKind.TK_ArrayType:
typeDst = SubstTypeCore(typeSrc = type.AsArrayType().GetElementType(), pctx);
return (typeDst == typeSrc) ? type : GetArray(typeDst, type.AsArrayType().rank);
case TypeKind.TK_PointerType:
typeDst = SubstTypeCore(typeSrc = type.AsPointerType().GetReferentType(), pctx);
return (typeDst == typeSrc) ? type : GetPointer(typeDst);
case TypeKind.TK_NullableType:
typeDst = SubstTypeCore(typeSrc = type.AsNullableType().GetUnderlyingType(), pctx);
return (typeDst == typeSrc) ? type : GetNullable(typeDst);
case TypeKind.TK_AggregateType:
if (type.AsAggregateType().GetTypeArgsAll().size > 0)
{
AggregateType ats = type.AsAggregateType();
TypeArray typeArgs = SubstTypeArray(ats.GetTypeArgsAll(), pctx);
if (ats.GetTypeArgsAll() != typeArgs)
return GetAggregate(ats.getAggregate(), typeArgs);
}
return type;
case TypeKind.TK_ErrorType:
if (type.AsErrorType().HasParent())
{
ErrorType err = type.AsErrorType();
Debug.Assert(err.nameText != null && err.typeArgs != null);
CType pParentType = null;
if (err.HasTypeParent())
{
pParentType = SubstTypeCore(err.GetTypeParent(), pctx);
}
TypeArray typeArgs = SubstTypeArray(err.typeArgs, pctx);
if (typeArgs != err.typeArgs || (err.HasTypeParent() && pParentType != err.GetTypeParent()))
{
return GetErrorType(pParentType, err.GetNSParent(), err.nameText, typeArgs);
}
}
return type;
case TypeKind.TK_TypeParameterType:
{
TypeParameterSymbol tvs = type.AsTypeParameterType().GetTypeParameterSymbol();
int index = tvs.GetIndexInTotalParameters();
if (tvs.IsMethodTypeParameter())
{
if ((pctx.grfst & SubstTypeFlags.DenormMeth) != 0 && tvs.parent != null)
return type;
Debug.Assert(tvs.GetIndexInOwnParameters() == tvs.GetIndexInTotalParameters());
if (index < pctx.ctypeMeth)
{
Debug.Assert(pctx.prgtypeMeth != null);
return pctx.prgtypeMeth[index];
}
else
{
return ((pctx.grfst & SubstTypeFlags.NormMeth) != 0 ? GetStdMethTypeVar(index) : type);
}
}
if ((pctx.grfst & SubstTypeFlags.DenormClass) != 0 && tvs.parent != null)
return type;
return index < pctx.ctypeCls ? pctx.prgtypeCls[index] :
((pctx.grfst & SubstTypeFlags.NormClass) != 0 ? GetStdClsTypeVar(index) : type);
}
}
}
示例7: GetBestAccessibleType
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// RUNTIME BINDER ONLY CHANGE
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
internal bool GetBestAccessibleType(CSemanticChecker semanticChecker, BindingContext bindingContext, CType typeSrc, out CType typeDst)
{
// This method implements the "best accessible type" algorithm for determining the type
// of untyped arguments in the runtime binder. It is also used in method type inference
// to fix type arguments to types that are accessible.
// The new type is returned in an out parameter. The result will be true (and the out param
// non-null) only when the algorithm could find a suitable accessible type.
Debug.Assert(semanticChecker != null);
Debug.Assert(bindingContext != null);
Debug.Assert(typeSrc != null);
typeDst = null;
if (semanticChecker.CheckTypeAccess(typeSrc, bindingContext.ContextForMemberLookup()))
{
// If we already have an accessible type, then use it. This is the terminal point of the recursion.
typeDst = typeSrc;
return true;
}
// These guys have no accessibility concerns.
Debug.Assert(!typeSrc.IsVoidType() && !typeSrc.IsErrorType() && !typeSrc.IsTypeParameterType());
if (typeSrc.IsParameterModifierType() || typeSrc.IsPointerType())
{
// We cannot vary these.
return false;
}
CType intermediateType;
if ((typeSrc.isInterfaceType() || typeSrc.isDelegateType()) && TryVarianceAdjustmentToGetAccessibleType(semanticChecker, bindingContext, typeSrc.AsAggregateType(), out intermediateType))
{
// If we have an interface or delegate type, then it can potentially be varied by its type arguments
// to produce an accessible type, and if that's the case, then return that.
// Example: IEnumerable<PrivateConcreteFoo> --> IEnumerable<PublicAbstractFoo>
typeDst = intermediateType;
Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, bindingContext.ContextForMemberLookup()));
return true;
}
if (typeSrc.IsArrayType() && TryArrayVarianceAdjustmentToGetAccessibleType(semanticChecker, bindingContext, typeSrc.AsArrayType(), out intermediateType))
{
// Similarly to the interface and delegate case, arrays are covariant in their element type and
// so we can potentially produce an array type that is accessible.
// Example: PrivateConcreteFoo[] --> PublicAbstractFoo[]
typeDst = intermediateType;
Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, bindingContext.ContextForMemberLookup()));
return true;
}
if (typeSrc.IsNullableType())
{
// We have an inaccessible nullable type, which means that the best we can do is System.ValueType.
typeDst = this.GetOptPredefAgg(PredefinedType.PT_VALUE).getThisType();
Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, bindingContext.ContextForMemberLookup()));
return true;
}
if (typeSrc.IsArrayType())
{
// We have an inaccessible array type for which we could not earlier find a better array type
// with a covariant conversion, so the best we can do is System.Array.
typeDst = this.GetReqPredefAgg(PredefinedType.PT_ARRAY).getThisType();
Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, bindingContext.ContextForMemberLookup()));
return true;
}
Debug.Assert(typeSrc.IsAggregateType());
if (typeSrc.IsAggregateType())
{
// We have an AggregateType, so recurse on its base class.
AggregateType aggType = typeSrc.AsAggregateType();
AggregateType baseType = aggType.GetBaseClass();
if (baseType == null)
{
// This happens with interfaces, for instance. But in that case, the
// conversion to object does exist, is an implicit reference conversion,
// and so we will use it.
baseType = this.GetReqPredefAgg(PredefinedType.PT_OBJECT).getThisType();
}
return GetBestAccessibleType(semanticChecker, bindingContext, baseType, out typeDst);
}
return false;
}
示例8: conversion
/***************************************************************************************************
Determine whether there is an explicit or implicit reference conversion (or identity conversion)
from typeSrc to typeDst. This is when:
13.2.3 Explicit reference conversions
The explicit reference conversions are:
* From object to any reference-type.
* From any class-type S to any class-type T, provided S is a base class of T.
* From any class-type S to any interface-type T, provided S is not sealed and provided S does not implement T.
* From any interface-type S to any class-type T, provided T is not sealed or provided T implements S.
* From any interface-type S to any interface-type T, provided S is not derived from T.
* From an array-type S with an element type SE to an array-type T with an element type TE, provided all of the following are true:
o S and T differ only in element type. (In other words, S and T have the same number of dimensions.)
o An explicit reference conversion exists from SE to TE.
* From System.Array and the interfaces it implements, to any array-type.
* From System.Delegate and the interfaces it implements, to any delegate-type.
* From a one-dimensional array-type S[] to System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T> and their base interfaces, provided there is an explicit reference conversion from S to T.
* From a generic delegate type S to generic delegate type T, provided all of the follow are true:
o Both types are constructed generic types of the same generic delegate type, D<X1,... Xk>.That is,
S is D<S1,... Sk> and T is D<T1,... Tk>.
o S is not compatible with or identical to T.
o If type parameter Xi is declared to be invariant then Si must be identical to Ti.
o If type parameter Xi is declared to be covariant ("out") then Si must be convertible
to Ti via an identify conversion, implicit reference conversion, or explicit reference conversion.
o If type parameter Xi is declared to be contravariant ("in") then either Si must be identical to Ti,
or Si and Ti must both be reference types.
* From System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T> and their base interfaces to a one-dimensional array-type S[], provided there is an implicit or explicit reference conversion from S[] to System.Collections.Generic.IList<T> or System.Collections.Generic.IReadOnlyList<T>. This is precisely when either S and T are the same type or there is an implicit or explicit reference conversion from S to T.
For a type-parameter T that is known to be a reference type (§25.7), the following explicit reference conversions exist:
* From the effective base class C of T to T and from any base class of C to T.
* From any interface-type to T.
* From T to any interface-type I provided there isn’t already an implicit reference conversion from T to I.
* From a type-parameter U to T provided that T depends on U (§25.7). [Note: Since T is known to be a reference type, within the scope of T, the run-time type of U will always be a reference type, even if U is not known to be a reference type at compile-time. end note]
* Both src and dst are reference types and there is a builtin explicit conversion from
src to dst.
* Or src is a reference type and dst is a base type of src (in which case the conversion is
implicit as well).
* Or dst is a reference type and src is a base type of dst.
The latter two cases can happen with type variables even though the other type variable is not
a reference type.
***************************************************************************************************/
public static bool FExpRefConv(SymbolLoader loader, CType typeSrc, CType typeDst)
{
Debug.Assert(typeSrc != null);
Debug.Assert(typeDst != null);
if (typeSrc.IsRefType() && typeDst.IsRefType())
{
// is there an implicit reference conversion in either direction?
// this handles the bulk of the cases ...
if (loader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst) ||
loader.HasIdentityOrImplicitReferenceConversion(typeDst, typeSrc))
{
return true;
}
// For a type-parameter T that is known to be a reference type (§25.7), the following explicit reference conversions exist:
// • From any interface-type to T.
// • From T to any interface-type I provided there isn’t already an implicit reference conversion from T to I.
if (typeSrc.isInterfaceType() && typeDst.IsTypeParameterType())
{
return true;
}
if (typeSrc.IsTypeParameterType() && typeDst.isInterfaceType())
{
return true;
}
// * From any class-type S to any interface-type T, provided S is not sealed
// * From any interface-type S to any class-type T, provided T is not sealed
// * From any interface-type S to any interface-type T, provided S is not derived from T.
if (typeSrc.IsAggregateType() && typeDst.IsAggregateType())
{
AggregateSymbol aggSrc = typeSrc.AsAggregateType().getAggregate();
AggregateSymbol aggDest = typeDst.AsAggregateType().getAggregate();
if ((aggSrc.IsClass() && !aggSrc.IsSealed() && aggDest.IsInterface()) ||
(aggSrc.IsInterface() && aggDest.IsClass() && !aggDest.IsSealed()) ||
(aggSrc.IsInterface() && aggDest.IsInterface()))
{
return true;
}
}
// * From an array-type S with an element type SE to an array-type T with an element type TE, provided all of the following are true:
// o S and T differ only in element type. (In other words, S and T have the same number of dimensions.)
// o An explicit reference conversion exists from SE to TE.
if (typeSrc.IsArrayType() && typeDst.IsArrayType())
{
return typeSrc.AsArrayType().rank == typeDst.AsArrayType().rank && FExpRefConv(loader, typeSrc.AsArrayType().GetElementType(), typeDst.AsArrayType().GetElementType());
}
// * From a one-dimensional array-type S[] to System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T>
// and their base interfaces, provided there is an explicit reference conversion from S to T.
if (typeSrc.IsArrayType())
{
if (typeSrc.AsArrayType().rank != 1 ||
!typeDst.isInterfaceType() || typeDst.AsAggregateType().GetTypeArgsAll().Size != 1)
//.........这里部分代码省略.........
示例9: HasImplicitReferenceConversion
public bool HasImplicitReferenceConversion(CType pSource, CType pDest)
{
Debug.Assert(pSource != null);
Debug.Assert(pDest != null);
// The implicit reference conversions are:
// * From any reference type to Object.
if (pSource.IsRefType() && pDest.isPredefType(PredefinedType.PT_OBJECT))
{
return true;
}
// * From any class type S to any class type T provided S is derived from T.
if (pSource.isClassType() && pDest.isClassType() && IsBaseClass(pSource, pDest))
{
return true;
}
// ORIGINAL RULES:
// // * From any class type S to any interface type T provided S implements T.
// if (pSource.isClassType() && pDest.isInterfaceType() && IsBaseInterface(pSource, pDest))
// {
// return true;
// }
// // * from any interface type S to any interface type T, provided S is derived from T.
// if (pSource.isInterfaceType() && pDest.isInterfaceType() && IsBaseInterface(pSource, pDest))
// {
// return true;
// }
// VARIANCE EXTENSIONS:
// * From any class type S to any interface type T provided S implements an interface
// convertible to T.
// * From any interface type S to any interface type T provided S implements an interface
// convertible to T.
// * From any interface type S to any interface type T provided S is not T and S is
// an interface convertible to T.
if (pSource.isClassType() && pDest.isInterfaceType() && HasAnyBaseInterfaceConversion(pSource, pDest))
{
return true;
}
if (pSource.isInterfaceType() && pDest.isInterfaceType() && HasAnyBaseInterfaceConversion(pSource, pDest))
{
return true;
}
if (pSource.isInterfaceType() && pDest.isInterfaceType() && pSource != pDest &&
HasInterfaceConversion(pSource.AsAggregateType(), pDest.AsAggregateType()))
{
return true;
}
// * From an array type S with an element type SE to an array type T with element type TE
// provided that all of the following are true:
// * S and T differ only in element type. In other words, S and T have the same number of dimensions.
// * Both SE and TE are reference types.
// * An implicit reference conversion exists from SE to TE.
if (pSource.IsArrayType() && pDest.IsArrayType() &&
HasCovariantArrayConversion(pSource.AsArrayType(), pDest.AsArrayType()))
{
return true;
}
// * From any array type to System.Array or any interface implemented by System.Array.
if (pSource.IsArrayType() && (pDest.isPredefType(PredefinedType.PT_ARRAY) ||
IsBaseInterface(GetReqPredefType(PredefinedType.PT_ARRAY, false), pDest)))
{
return true;
}
// * From a single-dimensional array type S[] to IList<T> and its base
// interfaces, provided that there is an implicit identity or reference
// conversion from S to T.
if (pSource.IsArrayType() && HasArrayConversionToInterface(pSource.AsArrayType(), pDest))
{
return true;
}
// * From any delegate type to System.Delegate
//
// SPEC OMISSION:
//
// The spec should actually say
//
// * From any delegate type to System.Delegate
// * From any delegate type to System.MulticastDelegate
// * From any delegate type to any interface implemented by System.MulticastDelegate
if (pSource.isDelegateType() &&
(pDest.isPredefType(PredefinedType.PT_MULTIDEL) ||
pDest.isPredefType(PredefinedType.PT_DELEGATE) ||
IsBaseInterface(GetReqPredefType(PredefinedType.PT_MULTIDEL, false), pDest)))
{
return true;
}
// VARIANCE EXTENSION:
// * From any delegate type S to a delegate type T provided S is not T and
// S is a delegate convertible to T
if (pSource.isDelegateType() && pDest.isDelegateType() &&
HasDelegateConversion(pSource.AsAggregateType(), pDest.AsAggregateType()))
{
return true;
//.........这里部分代码省略.........
示例10: ErrAppendType
//.........这里部分代码省略.........
// Load the string "<error>".
Debug.Assert(null == pType.AsErrorType().typeArgs);
ErrAppendId(MessageID.ERRORSYM);
}
break;
case TypeKind.TK_NullType:
// Load the string "<null>".
ErrAppendId(MessageID.NULL);
break;
case TypeKind.TK_OpenTypePlaceholderType:
// Leave blank.
break;
case TypeKind.TK_BoundLambdaType:
ErrAppendId(MessageID.AnonMethod);
break;
case TypeKind.TK_UnboundLambdaType:
ErrAppendId(MessageID.Lambda);
break;
case TypeKind.TK_MethodGroupType:
ErrAppendId(MessageID.MethodGroup);
break;
case TypeKind.TK_ArgumentListType:
ErrAppendString(TokenFacts.GetText(TokenKind.ArgList));
break;
case TypeKind.TK_ArrayType:
{
CType elementType = pType.AsArrayType().GetBaseElementType();
int rank;
if (null == elementType)
{
Debug.Assert(false, "No element type");
break;
}
ErrAppendType(elementType, pctx);
for (elementType = pType;
elementType != null && elementType.IsArrayType();
elementType = elementType.AsArrayType().GetElementType())
{
rank = elementType.AsArrayType().rank;
// Add [] with (rank-1) commas inside
ErrAppendChar('[');
#if ! CSEE
// known rank.
if (rank > 1)
{
ErrAppendChar('*');
}
#endif
for (int i = rank; i > 1; --i)
{
ErrAppendChar(',');
#if ! CSEE