// Copyright (c) AlphaSierraPapa for the SharpDevelop Team // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software // without restriction, including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons // to whom the Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all copies or // substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. using System; using System.Collections.Generic; namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { internal class Generics { private class GenericClass { private readonly T issue1760; public void M(out GenericClass self) { self = this; } public void Issue1760() { Console.WriteLine(", " + issue1760); } } public class BaseClass { } public class DerivedClass : BaseClass { } public class MyArray { public class NestedClass { public T Item1; public Y Item2; } public enum NestedEnum { A, B } private T[] arr; public MyArray(int capacity) { arr = new T[capacity]; } public void Size(int capacity) { Array.Resize(ref arr, capacity); } public void Grow(int capacity) { if (capacity >= arr.Length) { Size(capacity); } } } public interface IInterface { void Method1() where T : class; void Method2() where T : class; } public abstract class Base : IInterface { // constraints must be repeated on implicit interface implementation public abstract void Method1() where T : class; // constraints must not be specified on explicit interface implementation void IInterface.Method2() { } } public class Derived : Base { // constraints are inherited automatically and must not be specified public override void Method1() { } } private const MyArray.NestedEnum enumVal = MyArray.NestedEnum.A; private static Type type1 = typeof(List<>); private static Type type2 = typeof(MyArray<>); private static Type type3 = typeof(List<>.Enumerator); private static Type type4 = typeof(MyArray<>.NestedClass<>); private static Type type5 = typeof(List[]); private static Type type6 = typeof(MyArray<>.NestedEnum); public T CastToTypeParameter(DerivedClass d) where T : BaseClass { return (T)(BaseClass)d; } public TTarget GenericAsGeneric(TSource source) where TTarget : class { return source as TTarget; } public TTarget? GenericAsNullable(TSource source) where TTarget : struct { return source as TTarget?; } public TTarget ObjectAsGeneric(object source) where TTarget : class { return source as TTarget; } public TTarget? ObjectAsNullable(object source) where TTarget : struct { return source as TTarget?; } public TTarget IntAsGeneric(int source) where TTarget : class { return source as TTarget; } public TTarget? IntAsNullable(int source) where TTarget : struct { return source as TTarget?; } public T New() where T : new() { return new T(); } public T NotNew() { return Activator.CreateInstance(); } public bool IsNull(T t) { return t == null; } public T[] NewArray(int size) { return new T[size]; } public T[,] NewArray(int size1, int size2) { return new T[size1, size2]; } public Type[] TestTypeOf() { return new Type[8] { typeof(int), typeof(int[]), typeof(GenericClass<>), typeof(GenericClass), typeof(GenericClass), typeof(Dictionary<, >), typeof(List.Enumerator), typeof(List<>.Enumerator) }; } public static void MethodWithConstraint() where T : class, S where S : ICloneable, new() { } public static void MethodWithStructConstraint() where T : struct { } private static void MultidimensionalArray(T[,] array) { array[0, 0] = array[0, 1]; } public static Dictionary.KeyCollection.Enumerator GetEnumerator(Dictionary d, MyArray.NestedClass nc) { // Tests references to inner classes in generic classes return d.Keys.GetEnumerator(); } public static bool IsString(T input) { return input is string; } public static string AsString(T input) { return input as string; } public static string CastToString(T input) { return (string)(object)input; } public static T CastFromString(string input) { return (T)(object)input; } public static bool IsInt(T input) { return input is int; } public static int CastToInt(T input) { return (int)(object)input; } public static T CastFromInt(int input) { return (T)(object)input; } public static bool IsNullableInt(T input) { return input is int?; } public static int? AsNullableInt(T input) { return input as int?; } public static int? CastToNullableInt(T input) { return (int?)(object)input; } public static T CastFromNullableInt(int? input) { return (T)(object)input; } #if CS73 public static object CallDelegate(T input) where T : Delegate { return input.DynamicInvoke(); } public static int CountEnumerators() where T : Enum { return typeof(T).GetEnumValues().Length; } public unsafe static int UnmanagedConstraint() where T : unmanaged { return sizeof(T); } #endif public static void Issue1959(int a, int b, int? c) { // This line requires parentheses around `a < b` to avoid a grammar ambiguity. Console.WriteLine("{}, {}", (a < b), a > (c ?? b)); // But here there's no ambiguity: Console.WriteLine("{}, {}", a < b, a > b); Console.WriteLine("{}, {}", a < Environment.GetLogicalDrives().Length, a > (c ?? b)); } public static Type Issue2231() { return default(T).GetType(); } public static string Issue2231b() { return default(T).ToString(); } } }