本文整理汇总了C#中Microsoft.CSharp.RuntimeBinder.Semantics.CType.AsTypeParameterType方法的典型用法代码示例。如果您正苦于以下问题:C# CType.AsTypeParameterType方法的具体用法?C# CType.AsTypeParameterType怎么用?C# CType.AsTypeParameterType使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Microsoft.CSharp.RuntimeBinder.Semantics.CType
的用法示例。
在下文中一共展示了CType.AsTypeParameterType方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: 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;
}
示例2: 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;
}
示例3: SubstEqualTypesCore
//.........这里部分代码省略.........
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.
for (int i = 0; i < errSrc.typeArgs.Size; i++)
{
if (!SubstEqualTypesCore(errDst.typeArgs.Item(i), errSrc.typeArgs.Item(i), pctx))
return false;
}
}
return true;
case TypeKind.TK_TypeParameterType:
{ // BLOCK
TypeParameterSymbol tvs = typeSrc.AsTypeParameterType().GetTypeParameterSymbol();
int index = tvs.GetIndexInTotalParameters();
if (tvs.IsMethodTypeParameter())
{
if ((pctx.grfst & SubstTypeFlags.DenormMeth) != 0 && tvs.parent != null)
{
// typeDst == typeSrc was handled above.
Debug.Assert(typeDst != typeSrc);
return false;
}
Debug.Assert(tvs.GetIndexInOwnParameters() == tvs.GetIndexInTotalParameters());
Debug.Assert(pctx.prgtypeMeth == null || tvs.GetIndexInTotalParameters() < pctx.ctypeMeth);
if (index < pctx.ctypeMeth && pctx.prgtypeMeth != null)
{
return typeDst == pctx.prgtypeMeth[index];
}
if ((pctx.grfst & SubstTypeFlags.NormMeth) != 0)
{
return typeDst == GetStdMethTypeVar(index);
}
}
else
{
if ((pctx.grfst & SubstTypeFlags.DenormClass) != 0 && tvs.parent != null)
{
// typeDst == typeSrc was handled above.
Debug.Assert(typeDst != typeSrc);
return false;
}
Debug.Assert(pctx.prgtypeCls == null || tvs.GetIndexInTotalParameters() < pctx.ctypeCls);
if (index < pctx.ctypeCls)
return typeDst == pctx.prgtypeCls[index];
if ((pctx.grfst & SubstTypeFlags.NormClass) != 0)
return typeDst == GetStdClsTypeVar(index);
}
}
return false;
}
}
示例4: TypeContainsTyVars
public static bool TypeContainsTyVars(CType type, TypeArray typeVars)
{
LRecurse: // Label used for "tail" recursion.
switch (type.GetTypeKind())
{
default:
Debug.Assert(false, "Bad Symbol kind in TypeContainsTyVars");
return false;
case TypeKind.TK_UnboundLambdaType:
case TypeKind.TK_BoundLambdaType:
case TypeKind.TK_NullType:
case TypeKind.TK_VoidType:
case TypeKind.TK_OpenTypePlaceholderType:
case TypeKind.TK_MethodGroupType:
return false;
case TypeKind.TK_ArrayType:
case TypeKind.TK_NullableType:
case TypeKind.TK_ParameterModifierType:
case TypeKind.TK_PointerType:
type = type.GetBaseOrParameterOrElementType();
goto LRecurse;
case TypeKind.TK_AggregateType:
{ // BLOCK
AggregateType ats = type.AsAggregateType();
for (int i = 0; i < ats.GetTypeArgsAll().Size; i++)
{
if (TypeContainsTyVars(ats.GetTypeArgsAll().Item(i), typeVars))
{
return true;
}
}
}
return false;
case TypeKind.TK_ErrorType:
if (type.AsErrorType().HasParent())
{
ErrorType err = type.AsErrorType();
Debug.Assert(err.nameText != null && err.typeArgs != null);
for (int i = 0; i < err.typeArgs.Size; i++)
{
if (TypeContainsTyVars(err.typeArgs.Item(i), typeVars))
{
return true;
}
}
if (err.HasTypeParent())
{
type = err.GetTypeParent();
goto LRecurse;
}
}
return false;
case TypeKind.TK_TypeParameterType:
if (typeVars != null && typeVars.Size > 0)
{
int ivar = type.AsTypeParameterType().GetIndexInTotalParameters();
return ivar < typeVars.Size && type == typeVars.Item(ivar);
}
return true;
}
}
示例5: CheckSingleConstraint
private static bool CheckSingleConstraint(CSemanticChecker checker, ErrorHandling errHandling, Symbol symErr, TypeParameterType var, CType arg, TypeArray typeArgsCls, TypeArray typeArgsMeth, CheckConstraintsFlags flags)
{
bool fReportErrors = 0 == (flags & CheckConstraintsFlags.NoErrors);
if (arg.IsOpenTypePlaceholderType())
{
return true;
}
if (arg.IsErrorType())
{
// Error should have been reported previously.
return false;
}
if (checker.CheckBogus(arg))
{
if (fReportErrors)
{
errHandling.ErrorRef(ErrorCode.ERR_BogusType, arg);
}
return false;
}
if (arg.IsPointerType() || arg.isSpecialByRefType())
{
if (fReportErrors)
{
errHandling.Error(ErrorCode.ERR_BadTypeArgument, arg);
}
return false;
}
if (arg.isStaticClass())
{
if (fReportErrors)
{
checker.ReportStaticClassError(null, arg, ErrorCode.ERR_GenericArgIsStaticClass);
}
return false;
}
bool fError = false;
if (var.HasRefConstraint() && !arg.IsRefType())
{
if (fReportErrors)
{
errHandling.ErrorRef(ErrorCode.ERR_RefConstraintNotSatisfied, symErr, new ErrArgNoRef(var), arg);
}
fError = true;
}
TypeArray bnds = checker.GetSymbolLoader().GetTypeManager().SubstTypeArray(var.GetBounds(), typeArgsCls, typeArgsMeth);
int itypeMin = 0;
if (var.HasValConstraint())
{
// If we have a type variable that is constrained to a value type, then we
// want to check if its a nullable type, so that we can report the
// constraint error below. In order to do this however, we need to check
// that either the type arg is not a value type, or it is a nullable type.
//
// To check whether or not its a nullable type, we need to get the resolved
// bound from the type argument and check against that.
bool bIsValueType = arg.IsValType();
bool bIsNullable = arg.IsNullableType();
if (bIsValueType && arg.IsTypeParameterType())
{
TypeArray pArgBnds = arg.AsTypeParameterType().GetBounds();
if (pArgBnds.size > 0)
{
bIsNullable = pArgBnds.Item(0).IsNullableType();
}
}
if (!bIsValueType || bIsNullable)
{
if (fReportErrors)
{
errHandling.ErrorRef(ErrorCode.ERR_ValConstraintNotSatisfied, symErr, new ErrArgNoRef(var), arg);
}
fError = true;
}
// Since FValCon() is set it is redundant to check System.ValueType as well.
if (bnds.size != 0 && bnds.Item(0).isPredefType(PredefinedType.PT_VALUE))
{
itypeMin = 1;
}
}
for (int j = itypeMin; j < bnds.size; j++)
{
CType typeBnd = bnds.Item(j);
//.........这里部分代码省略.........
示例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: HasBaseConversion
public bool HasBaseConversion(CType pSource, CType pDest)
{
// By a "base conversion" we mean:
//
// * an identity conversion
// * an implicit reference conversion
// * an implicit boxing conversion
// * an implicit type parameter conversion
//
// In other words, these are conversions that can be made to a base
// class, base interface or co/contravariant type without any change in
// representation other than boxing. A conversion from, say, int to double,
// is NOT a "base conversion", because representation is changed. A conversion
// from, say, lambda to expression tree is not a "base conversion" because
// do not have a type.
//
// The existence of a base conversion depends solely upon the source and
// destination types, not the source expression.
//
// This notion is not found in the spec but it is useful in the implementation.
if (pSource.IsAggregateType() && pDest.isPredefType(PredefinedType.PT_OBJECT))
{
// If we are going from any aggregate type (class, struct, interface, enum or delegate)
// to object, we immediately return true. This may seem like a mere optimization --
// after all, if we have an aggregate then we have some kind of implicit conversion
// to object.
//
// However, it is not a mere optimization; this introduces a control flow change
// in error reporting scenarios for unresolved type forwarders. If a type forwarder
// cannot be resolved then the resulting type symbol will be an aggregate, but
// we will not be able to classify it into class, struct, etc.
//
// We know that we will have an error in this case; we do not wish to compound
// that error by giving a spurious "you cannot convert this thing to object"
// error, which, after all, will go away when the type forwarding problem is
// fixed.
return true;
}
if (HasIdentityOrImplicitReferenceConversion(pSource, pDest))
{
return true;
}
if (HasImplicitBoxingConversion(pSource, pDest))
{
return true;
}
if (pSource.IsTypeParameterType() &&
HasImplicitTypeParameterBaseConversion(pSource.AsTypeParameterType(), pDest))
{
return true;
}
return false;
}
示例8: ErrAppendType
public void ErrAppendType(CType pType, SubstContext pctx, bool fArgs)
{
if (pctx != null)
{
if (!pctx.FNop())
{
pType = GetTypeManager().SubstType(pType, pctx);
}
// We shouldn't use the SubstContext again so set it to NULL.
pctx = null;
}
switch (pType.GetTypeKind())
{
case TypeKind.TK_AggregateType:
{
AggregateType pAggType = pType.AsAggregateType();
// Check for a predefined class with a special "nice" name for
// error reported.
string text = PredefinedTypes.GetNiceName(pAggType.getAggregate());
if (text != null)
{
// Found a nice name.
ErrAppendString(text);
}
else if (pAggType.getAggregate().IsAnonymousType())
{
ErrAppendPrintf("AnonymousType#{0}", GetTypeID(pAggType));
break;
}
else
{
if (pAggType.outerType != null)
{
ErrAppendType(pAggType.outerType, pctx);
ErrAppendChar('.');
}
else
{
// In a namespace.
ErrAppendParentSym(pAggType.getAggregate(), pctx);
}
ErrAppendName(pAggType.getAggregate().name);
}
ErrAppendTypeParameters(pAggType.GetTypeArgsThis(), pctx, true);
break;
}
case TypeKind.TK_TypeParameterType:
if (null == pType.GetName())
{
// It's a standard type variable.
if (pType.AsTypeParameterType().IsMethodTypeParameter())
{
ErrAppendChar('!');
}
ErrAppendChar('!');
ErrAppendPrintf("{0}", pType.AsTypeParameterType().GetIndexInTotalParameters());
}
else
{
ErrAppendName(pType.GetName());
}
break;
case TypeKind.TK_ErrorType:
if (pType.AsErrorType().HasParent())
{
Debug.Assert(pType.AsErrorType().nameText != null && pType.AsErrorType().typeArgs != null);
ErrAppendParentType(pType, pctx);
ErrAppendName(pType.AsErrorType().nameText);
ErrAppendTypeParameters(pType.AsErrorType().typeArgs, pctx, true);
}
else
{
// 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:
//.........这里部分代码省略.........
示例9: HasImplicitTypeParameterBaseConversion
private bool HasImplicitTypeParameterBaseConversion(
TypeParameterType pSource, CType pDest)
{
Debug.Assert(pSource != null);
Debug.Assert(pDest != null);
if (HasImplicitReferenceTypeParameterConversion(pSource, pDest))
{
return true;
}
if (HasImplicitBoxingTypeParameterConversion(pSource, pDest))
{
return true;
}
if (pDest.IsTypeParameterType() && pSource.DependsOn(pDest.AsTypeParameterType()))
{
return true;
}
return false;
}
示例10: HasImplicitBoxingConversion
public bool HasImplicitBoxingConversion(CType pSource, CType pDest)
{
Debug.Assert(pSource != null);
Debug.Assert(pDest != null);
// Certain type parameter conversions are classified as boxing conversions.
if (pSource.IsTypeParameterType() &&
HasImplicitBoxingTypeParameterConversion(pSource.AsTypeParameterType(), pDest))
{
return true;
}
// The rest of the boxing conversions only operate when going from a value type
// to a reference type.
if (!pSource.IsValType() || !pDest.IsRefType())
{
return false;
}
// A boxing conversion exists from a nullable type to a reference type
// if and only if a boxing conversion exists from the underlying type.
if (pSource.IsNullableType())
{
return HasImplicitBoxingConversion(pSource.AsNullableType().GetUnderlyingType(), pDest);
}
// A boxing conversion exists from any non-nullable value type to object,
// to System.ValueType, and to any interface type implemented by the
// non-nullable value type. Furthermore, an enum type can be converted
// to the type System.Enum.
// We set the base class of the structs to System.ValueType, System.Enum, etc,
// so we can just check here.
if (IsBaseClass(pSource, pDest))
{
return true;
}
if (HasAnyBaseInterfaceConversion(pSource, pDest))
{
return true;
}
return false;
}
示例11: HasImplicitReferenceTypeParameterConversion
private bool HasImplicitReferenceTypeParameterConversion(
TypeParameterType pSource, CType pDest)
{
Debug.Assert(pSource != null);
Debug.Assert(pDest != null);
if (!pSource.IsRefType())
{
// Not a reference conversion.
return false;
}
// The following implicit conversions exist for a given type parameter T:
//
// * From T to its effective base class C.
AggregateType pEBC = pSource.GetEffectiveBaseClass();
if (pDest == pEBC)
{
return true;
}
// * From T to any base class of C.
if (IsBaseClass(pEBC, pDest))
{
return true;
}
// * From T to any interface implemented by C.
if (IsBaseInterface(pEBC, pDest))
{
return true;
}
// * From T to any interface type I in T's effective interface set, and
// from T to any base interface of I.
TypeArray pInterfaces = pSource.GetInterfaceBounds();
for (int i = 0; i < pInterfaces.Size; ++i)
{
if (pInterfaces.Item(i) == pDest)
{
return true;
}
}
// * From T to a type parameter U, provided T depends on U.
if (pDest.IsTypeParameterType() && pSource.DependsOn(pDest.AsTypeParameterType()))
{
return true;
}
return false;
}
示例12: HasImplicitReferenceConversion
//.........这里部分代码省略.........
// }
// 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;
}
// * From the null literal to any reference type
// NOTE: We extend the specification here. The C# 3.0 spec does not describe
// a "null type". Rather, it says that the null literal is typeless, and is
// convertible to any reference or nullable type. However, the C# 2.0 and 3.0
// implementations have a "null type" which some expressions other than the
// null literal may have. (For example, (null??null), which is also an
// extension to the specification.)
if (pSource.IsNullType() && pDest.IsRefType())
{
return true;
}
if (pSource.IsNullType() && pDest.IsNullableType())
{
return true;
}
// * Implicit conversions involving type parameters that are known to be reference types.
if (pSource.IsTypeParameterType() &&
HasImplicitReferenceTypeParameterConversion(pSource.AsTypeParameterType(), pDest))
{
return true;
}
return false;
}
示例13: GetAggTypeSym
// It would be nice to make this a virtual method on typeSym.
public AggregateType GetAggTypeSym(CType typeSym)
{
Debug.Assert(typeSym != null);
Debug.Assert(typeSym.IsAggregateType() ||
typeSym.IsTypeParameterType() ||
typeSym.IsArrayType() ||
typeSym.IsNullableType());
switch (typeSym.GetTypeKind())
{
case TypeKind.TK_AggregateType:
return typeSym.AsAggregateType();
case TypeKind.TK_ArrayType:
return GetReqPredefType(PredefinedType.PT_ARRAY);
case TypeKind.TK_TypeParameterType:
return typeSym.AsTypeParameterType().GetEffectiveBaseClass();
case TypeKind.TK_NullableType:
return typeSym.AsNullableType().GetAts(ErrorContext);
}
Debug.Assert(false, "Bad typeSym!");
return null;
}
示例14: LowerBoundClassInference
////////////////////////////////////////////////////////////////////////////////
private bool LowerBoundClassInference(CType pSource, AggregateType pDest)
{
if (!pDest.isClassType())
{
return false;
}
// SPEC: Otherwise, if V is a class CType C<V1...Vk> and U is a class CType which
// SPEC: inherits directly or indirectly from C<U1...Uk>
// SPEC: then an exact inference is made from each Ui to the corresponding Vi.
// SPEC: Otherwise, if V is a class CType C<V1...Vk> and U is a CType parameter
// SPEC: with effective base class C<U1...Uk>
// SPEC: then an exact inference is made from each Ui to the corresponding Vi.
// SPEC: Otherwise, if V is a class CType C<V1...Vk> and U is a CType parameter
// SPEC: with an effective base class which inherits directly or indirectly from
// SPEC: C<U1...Uk> then an exact inference is made
// SPEC: from each Ui to the corresponding Vi.
AggregateType pSourceBase = null;
if (pSource.isClassType())
{
pSourceBase = pSource.AsAggregateType().GetBaseClass();
}
else if (pSource.IsTypeParameterType())
{
pSourceBase = pSource.AsTypeParameterType().GetEffectiveBaseClass();
}
while (pSourceBase != null)
{
if (pSourceBase.GetOwningAggregate() == pDest.GetOwningAggregate())
{
ExactTypeArgumentInference(pSourceBase, pDest);
return true;
}
pSourceBase = pSourceBase.GetBaseClass();
}
return false;
}
示例15: GetUserDefinedBinopArgumentType
private AggregateType GetUserDefinedBinopArgumentType(CType type)
{
for (; ;)
{
switch (type.GetTypeKind())
{
case TypeKind.TK_NullableType:
type = type.StripNubs();
break;
case TypeKind.TK_TypeParameterType:
type = type.AsTypeParameterType().GetEffectiveBaseClass();
break;
case TypeKind.TK_AggregateType:
if ((type.isClassType() || type.isStructType()) && !type.AsAggregateType().getAggregate().IsSkipUDOps())
{
return type.AsAggregateType();
}
return null;
default:
return null;
}
}
}