本文整理汇总了C#中Microsoft.CSharp.RuntimeBinder.Semantics.CType.IsNullableType方法的典型用法代码示例。如果您正苦于以下问题:C# CType.IsNullableType方法的具体用法?C# CType.IsNullableType怎么用?C# CType.IsNullableType使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Microsoft.CSharp.RuntimeBinder.Semantics.CType
的用法示例。
在下文中一共展示了CType.IsNullableType方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: CheckAccess2
public virtual ACCESSERROR CheckAccess2(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru)
{
Debug.Assert(symCheck != null);
Debug.Assert(atsCheck == null || symCheck.parent == atsCheck.getAggregate());
Debug.Assert(typeThru == null ||
typeThru.IsAggregateType() ||
typeThru.IsTypeParameterType() ||
typeThru.IsArrayType() ||
typeThru.IsNullableType() ||
typeThru.IsErrorType());
#if DEBUG
switch (symCheck.getKind())
{
default:
break;
case SYMKIND.SK_MethodSymbol:
case SYMKIND.SK_PropertySymbol:
case SYMKIND.SK_FieldSymbol:
case SYMKIND.SK_EventSymbol:
Debug.Assert(atsCheck != null);
break;
}
#endif // DEBUG
ACCESSERROR error = CheckAccessCore(symCheck, atsCheck, symWhere, typeThru);
if (ACCESSERROR.ACCESSERROR_NOERROR != error)
{
return error;
}
// Check the accessibility of the return CType.
CType CType = symCheck.getType();
if (CType == null)
{
return ACCESSERROR.ACCESSERROR_NOERROR;
}
// For members of AGGSYMs, atsCheck should always be specified!
Debug.Assert(atsCheck != null);
if (atsCheck.getAggregate().IsSource())
{
// We already check the "at least as accessible as" rules.
// Does this always work for generics?
// Could we get a bad CType argument in typeThru?
// Maybe call CheckTypeAccess on typeThru?
return ACCESSERROR.ACCESSERROR_NOERROR;
}
// Substitute on the CType.
if (atsCheck.GetTypeArgsAll().size > 0)
{
CType = SymbolLoader.GetTypeManager().SubstType(CType, atsCheck);
}
return CheckTypeAccess(CType, symWhere) ? ACCESSERROR.ACCESSERROR_NOERROR : ACCESSERROR.ACCESSERROR_NOACCESS;
}
示例2: CheckAccessCore
//
// SymbolLoader forwarders (end)
/////////////////////////////////////////////////////////////////////////////////
//
// Utility methods
//
protected ACCESSERROR CheckAccessCore(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru)
{
Debug.Assert(symCheck != null);
Debug.Assert(atsCheck == null || symCheck.parent == atsCheck.getAggregate());
Debug.Assert(typeThru == null ||
typeThru.IsAggregateType() ||
typeThru.IsTypeParameterType() ||
typeThru.IsArrayType() ||
typeThru.IsNullableType() ||
typeThru.IsErrorType());
switch (symCheck.GetAccess())
{
default:
throw Error.InternalCompilerError();
//return ACCESSERROR.ACCESSERROR_NOACCESS;
case ACCESS.ACC_UNKNOWN:
return ACCESSERROR.ACCESSERROR_NOACCESS;
case ACCESS.ACC_PUBLIC:
return ACCESSERROR.ACCESSERROR_NOERROR;
case ACCESS.ACC_PRIVATE:
case ACCESS.ACC_PROTECTED:
if (symWhere == null)
{
return ACCESSERROR.ACCESSERROR_NOACCESS;
}
break;
case ACCESS.ACC_INTERNAL:
case ACCESS.ACC_INTERNALPROTECTED: // Check internal, then protected.
if (symWhere == null)
{
return ACCESSERROR.ACCESSERROR_NOACCESS;
}
if (symWhere.SameAssemOrFriend(symCheck))
{
return ACCESSERROR.ACCESSERROR_NOERROR;
}
if (symCheck.GetAccess() == ACCESS.ACC_INTERNAL)
{
return ACCESSERROR.ACCESSERROR_NOACCESS;
}
break;
}
// Should always have atsCheck for private and protected access check.
// We currently don't need it since access doesn't respect instantiation.
// We just use symWhere.parent.AsAggregateSymbol() instead.
AggregateSymbol aggCheck = symCheck.parent.AsAggregateSymbol();
// Find the inner-most enclosing AggregateSymbol.
AggregateSymbol aggWhere = null;
for (Symbol symT = symWhere; symT != null; symT = symT.parent)
{
if (symT.IsAggregateSymbol())
{
aggWhere = symT.AsAggregateSymbol();
break;
}
if (symT.IsAggregateDeclaration())
{
aggWhere = symT.AsAggregateDeclaration().Agg();
break;
}
}
if (aggWhere == null)
{
return ACCESSERROR.ACCESSERROR_NOACCESS;
}
// First check for private access.
for (AggregateSymbol agg = aggWhere; agg != null; agg = agg.GetOuterAgg())
{
if (agg == aggCheck)
{
return ACCESSERROR.ACCESSERROR_NOERROR;
}
}
if (symCheck.GetAccess() == ACCESS.ACC_PRIVATE)
{
return ACCESSERROR.ACCESSERROR_NOACCESS;
}
// Handle the protected case - which is the only real complicated one.
Debug.Assert(symCheck.GetAccess() == ACCESS.ACC_PROTECTED || symCheck.GetAccess() == ACCESS.ACC_INTERNALPROTECTED);
//.........这里部分代码省略.........
示例3: 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;
}
示例4: ExactNullableInference
////////////////////////////////////////////////////////////////////////////////
private bool ExactNullableInference(CType pSource, CType pDest)
{
// SPEC: Otherwise, if U is the CType U1? and V is the CType V1?
// SPEC: then an exact inference is made from U to V.
if (!pSource.IsNullableType() || !pDest.IsNullableType())
{
return false;
}
ExactInference(pSource.AsNullableType().GetUnderlyingType(),
pDest.AsNullableType().GetUnderlyingType());
return true;
}
示例5: GenerateOptionalArgument
/////////////////////////////////////////////////////////////////////////////////
private static EXPR GenerateOptionalArgument(
SymbolLoader symbolLoader,
ExprFactory exprFactory,
MethodOrPropertySymbol methprop,
CType type,
int index)
{
CType pParamType = type;
CType pRawParamType = type.IsNullableType() ? type.AsNullableType().GetUnderlyingType() : type;
EXPR optionalArgument = null;
if (methprop.HasDefaultParameterValue(index))
{
CType pConstValType = methprop.GetDefaultParameterValueConstValType(index);
CONSTVAL cv = methprop.GetDefaultParameterValue(index);
if (pConstValType.isPredefType(PredefinedType.PT_DATETIME) &&
(pRawParamType.isPredefType(PredefinedType.PT_DATETIME) || pRawParamType.isPredefType(PredefinedType.PT_OBJECT) || pRawParamType.isPredefType(PredefinedType.PT_VALUE)))
{
// This is the specific case where we want to create a DateTime
// but the constval that stores it is a long.
AggregateType dateTimeType = symbolLoader.GetReqPredefType(PredefinedType.PT_DATETIME);
optionalArgument = exprFactory.CreateConstant(dateTimeType, new CONSTVAL(DateTime.FromBinary(cv.longVal)));
}
else if (pConstValType.isSimpleOrEnumOrString())
{
// In this case, the constval is a simple type (all the numerics, including
// decimal), or an enum or a string. This covers all the substantial values,
// and everything else that can be encoded is just null or default(something).
// For enum parameters, we create a constant of the enum type. For everything
// else, we create the appropriate constant.
if (pRawParamType.isEnumType() && pConstValType == pRawParamType.underlyingType())
{
optionalArgument = exprFactory.CreateConstant(pRawParamType, cv);
}
else
{
optionalArgument = exprFactory.CreateConstant(pConstValType, cv);
}
}
else if ((pParamType.IsRefType() || pParamType.IsNullableType()) && cv.IsNullRef())
{
// We have an "= null" default value with a reference type or a nullable type.
optionalArgument = exprFactory.CreateNull();
}
else
{
// We have a default value that is encoded as a nullref, and that nullref is
// interpreted as default(something). For instance, the pParamType could be
// a type parameter type or a non-simple value type.
optionalArgument = exprFactory.CreateZeroInit(pParamType);
}
}
else
{
// There was no default parameter specified, so generally use default(T),
// except for some cases when the parameter type in metatdata is object.
if (pParamType.isPredefType(PredefinedType.PT_OBJECT))
{
if (methprop.MarshalAsObject(index))
{
// For [opt] parameters of type object, if we have marshal(iunknown),
// marshal(idispatch), or marshal(interface), then we emit a null.
optionalArgument = exprFactory.CreateNull();
}
else
{
// Otherwise, we generate Type.Missing
AggregateSymbol agg = symbolLoader.GetOptPredefAgg(PredefinedType.PT_MISSING);
Name name = symbolLoader.GetNameManager().GetPredefinedName(PredefinedName.PN_CAP_VALUE);
FieldSymbol field = symbolLoader.LookupAggMember(name, agg, symbmask_t.MASK_FieldSymbol).AsFieldSymbol();
FieldWithType fwt = new FieldWithType(field, agg.getThisType());
EXPRFIELD exprField = exprFactory.CreateField(0, agg.getThisType(), null, 0, fwt, null);
if (agg.getThisType() != type)
{
optionalArgument = exprFactory.CreateCast(0, type, exprField);
}
else
{
optionalArgument = exprField;
}
}
}
else
{
// Every type aside from object that doesn't have a default value gets
// its default value.
optionalArgument = exprFactory.CreateZeroInit(pParamType);
//.........这里部分代码省略.........
示例6: FWrappingConv
/***************************************************************************************************
Determines whether there is a wrapping conversion from typeSrc to typeDst
13.7 Conversions involving nullable types
The following terms are used in the subsequent sections:
* The term wrapping denotes the process of packaging a value, of type T, in an instance of type T?.
A value x of type T is wrapped to type T? by evaluating the expression new T?(x).
***************************************************************************************************/
public static bool FWrappingConv(CType typeSrc, CType typeDst)
{
return typeDst.IsNullableType() && typeSrc == typeDst.AsNullableType().GetUnderlyingType();
}
示例7: 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);
//.........这里部分代码省略.........
示例8: IsBaseClass
public bool IsBaseClass(CType pDerived, CType pBase)
{
Debug.Assert(pDerived != null);
Debug.Assert(pBase != null);
// A base class has got to be a class. The derived type might be a struct.
if (!pBase.isClassType())
{
return false;
}
if (pDerived.IsNullableType())
{
pDerived = pDerived.AsNullableType().GetAts(ErrorContext);
if (pDerived == null)
{
return false;
}
}
if (!pDerived.IsAggregateType())
{
return false;
}
AggregateType atsDer = pDerived.AsAggregateType();
AggregateType atsBase = pBase.AsAggregateType();
AggregateType atsCur = atsDer.GetBaseClass();
while (atsCur != null)
{
if (atsCur == atsBase)
{
return true;
}
atsCur = atsCur.GetBaseClass();
}
return false;
}
示例9: CanConvertArg2
/*
Same as CanConvertArg1 but with the indices interchanged!
*/
private bool CanConvertArg2(BinOpArgInfo info, CType typeDst, out LiftFlags pgrflt,
out CType ptypeSig1, out CType ptypeSig2)
{
Debug.Assert(!typeDst.IsNullableType());
ptypeSig1 = null;
ptypeSig2 = null;
if (canConvert(info.arg2, typeDst))
pgrflt = LiftFlags.None;
else
{
pgrflt = LiftFlags.None;
if (!GetSymbolLoader().FCanLift())
return false;
typeDst = GetSymbolLoader().GetTypeManager().GetNullable(typeDst);
if (!canConvert(info.arg2, typeDst))
return false;
pgrflt = LiftFlags.Convert2;
}
ptypeSig2 = typeDst;
if (info.type1.IsNullableType())
{
pgrflt = pgrflt | LiftFlags.Lift1;
ptypeSig1 = GetSymbolLoader().GetTypeManager().GetNullable(info.typeRaw1);
}
else
ptypeSig1 = info.typeRaw1;
return true;
}
示例10: RemapToOverride
////////////////////////////////////////////////////////////////////////////////
// For a base call we need to remap from the virtual to the specific override
// to invoke. This is also used to map a virtual on pObject (like ToString) to
// the specific override when the pObject is a simple type (int, bool, char,
// etc). In these cases it is safe to assume that any override won't later be
// removed.... We start searching from "typeObj" up the superclass hierarchy
// until we find a method with an exact signature match.
public static void RemapToOverride(SymbolLoader symbolLoader, SymWithType pswt, CType typeObj)
{
// For a property/indexer we remap the accessors, not the property/indexer.
// Since every event has both accessors we remap the event instead of the accessors.
Debug.Assert(pswt && (pswt.Sym.IsMethodSymbol() || pswt.Sym.IsEventSymbol() || pswt.Sym.IsMethodOrPropertySymbol()));
Debug.Assert(typeObj != null);
// Don't remap static or interface methods.
if (typeObj.IsNullableType())
{
typeObj = typeObj.AsNullableType().GetAts(symbolLoader.GetErrorContext());
if (typeObj == null)
{
VSFAIL("Why did GetAts return null?");
return;
}
}
// Don't remap non-virtual members
if (!typeObj.IsAggregateType() || typeObj.isInterfaceType() || !pswt.Sym.IsVirtual())
{
return;
}
symbmask_t mask = pswt.Sym.mask();
AggregateType atsObj = typeObj.AsAggregateType();
// Search for an override version of the method.
while (atsObj != null && atsObj.getAggregate() != pswt.Sym.parent)
{
for (Symbol symT = symbolLoader.LookupAggMember(pswt.Sym.name, atsObj.getAggregate(), mask);
symT != null;
symT = symbolLoader.LookupNextSym(symT, atsObj.getAggregate(), mask))
{
if (symT.IsOverride() && (symT.SymBaseVirtual() == pswt.Sym || symT.SymBaseVirtual() == pswt.Sym.SymBaseVirtual()))
{
pswt.Set(symT, atsObj);
return;
}
}
atsObj = atsObj.GetBaseClass();
}
}
示例11: LiftArgument
/////////////////////////////////////////////////////////////////////////////////
private void LiftArgument(EXPR pArgument, CType pParameterType, bool bConvertBeforeLift,
out EXPR ppLiftedArgument, out EXPR ppNonLiftedArgument)
{
EXPR pLiftedArgument = mustConvert(pArgument, pParameterType);
if (pLiftedArgument != pArgument)
{
MarkAsIntermediateConversion(pLiftedArgument);
}
EXPR pNonLiftedArgument = pArgument;
if (pParameterType.IsNullableType())
{
if (pNonLiftedArgument.isNull())
{
pNonLiftedArgument = mustCast(pNonLiftedArgument, pParameterType);
}
pNonLiftedArgument = mustCast(pNonLiftedArgument, pParameterType.AsNullableType().GetUnderlyingType());
if (bConvertBeforeLift)
{
MarkAsIntermediateConversion(pNonLiftedArgument);
}
}
else
{
pNonLiftedArgument = pLiftedArgument;
}
ppLiftedArgument = pLiftedArgument;
ppNonLiftedArgument = pNonLiftedArgument;
}
示例12: 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;
}
示例13: 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;
}
示例14: IsNullableValueType
protected bool IsNullableValueType(CType pType)
{
if (pType.IsNullableType())
{
CType pStrippedType = pType.StripNubs();
return pStrippedType.IsAggregateType() && pStrippedType.AsAggregateType().getAggregate().IsValueType();
}
return false;
}
示例15: CheckConstraints
// Check the constraints of any type arguments in the given Type.
public static bool CheckConstraints(CSemanticChecker checker, ErrorHandling errHandling, CType type, CheckConstraintsFlags flags)
{
type = type.GetNakedType(false);
if (type.IsNullableType())
{
CType typeT = type.AsNullableType().GetAts(checker.GetErrorContext());
if (typeT != null)
type = typeT;
else
type = type.GetNakedType(true);
}
if (!type.IsAggregateType())
return true;
AggregateType ats = type.AsAggregateType();
if (ats.GetTypeArgsAll().size == 0)
{
// Common case: there are no type vars, so there are no constraints.
ats.fConstraintsChecked = true;
ats.fConstraintError = false;
return true;
}
if (ats.fConstraintsChecked)
{
// Already checked.
if (!ats.fConstraintError || (flags & CheckConstraintsFlags.NoDupErrors) != 0)
{
// No errors or no need to report errors again.
return !ats.fConstraintError;
}
}
TypeArray typeVars = ats.getAggregate().GetTypeVars();
TypeArray typeArgsThis = ats.GetTypeArgsThis();
TypeArray typeArgsAll = ats.GetTypeArgsAll();
Debug.Assert(typeVars.size == typeArgsThis.size);
if (!ats.fConstraintsChecked)
{
ats.fConstraintsChecked = true;
ats.fConstraintError = false;
}
// Check the outer type first. If CheckConstraintsFlags.Outer is not specified and the
// outer type has already been checked then don't bother checking it.
if (ats.outerType != null && ((flags & CheckConstraintsFlags.Outer) != 0 || !ats.outerType.fConstraintsChecked))
{
CheckConstraints(checker, errHandling, ats.outerType, flags);
ats.fConstraintError |= ats.outerType.fConstraintError;
}
if (typeVars.size > 0)
ats.fConstraintError |= !CheckConstraintsCore(checker, errHandling, ats.getAggregate(), typeVars, typeArgsThis, typeArgsAll, null, (flags & CheckConstraintsFlags.NoErrors));
// Now check type args themselves.
for (int i = 0; i < typeArgsThis.size; i++)
{
CType arg = typeArgsThis.Item(i).GetNakedType(true);
if (arg.IsAggregateType() && !arg.AsAggregateType().fConstraintsChecked)
{
CheckConstraints(checker, errHandling, arg.AsAggregateType(), flags | CheckConstraintsFlags.Outer);
if (arg.AsAggregateType().fConstraintError)
ats.fConstraintError = true;
}
}
return !ats.fConstraintError;
}