// The Nova Project by Ken Beckett.
// Copyright (C) 2007-2012 Inevitable Software, all rights reserved.
// This file contains test code for the Nova.CodeDOM library - it's not designed to be
// executed, only parsed and resolved.
#pragma warning disable // disable warnings for this file
#undef JUST_TESTING // undefine symbol
#define UNDOCUMENTED // define symbol
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using Nova.CodeDOM;
using Win = System.Windows; // namespace alias
using App = System.Windows.Application; // type alias
using Attribute = System.Attribute;
[assembly: System.Reflection.AssemblyInformationalVersion("0.9")] // global attribute
namespace Test.Full
{
using System.Runtime.InteropServices;
/// <summary>
/// This is a custom attribute.
/// </summary>
[AttributeUsage(AttributeTargets.All)]
class CustomAttribute : Attribute
{
public string Message { get { return null; } set { } }
public int Value { get { return 0; } set { } }
}
// This is a top-level enum declaration
[Flags]
public enum TestEnum : byte
{
Zero,
#if true
One = 1, // EOL comment
#endif
#if true
// Regular comment
[Description("two")]
Two, // EOL comment
#else
Too,
#endif
Four = 4
}
/// <summary>
/// This is a class.
/// </summary>
[Custom(Message = "test", Value = 3)] // class attribute
#if true
public class TestClass
#else
class TestClass
#endif
: ArrayList, IDisposable
{
// ENUMS
// This is a nested enum declaration
enum E1 { One = 1, Two = 2 }
enum SingleEnum { LonelyValue }
// CONSTANTS & FIELDS
public const int MaxItems = 100;
[Obsolete("don't use")] // field attribute
private string _test;
private static TestClass _instance;
private double[,] _2darray;
private int _a, _b;
private int _c = 0, _d;
private const int E = MaxItems;
private TestEnum _testEnum = TestEnum.Four;
// CONSTRUCTORS & DESTRUCTORS
// Static constructor
static TestClass()
{
_instance = new TestClass();
_instance.Add(null); // base method call
}
/// <summary>
/// Doc comment with missing language element.
/// </summary>
//private int field;
/// <summary>Default constructor</summary>
/// test
public TestClass()
: base(/*infix*/)
{ }
/// <summary>
/// Constructor w/parameter.
/// </summary>
/// <param name="test">Test parameter.</param>
public TestClass(string test)
: this()
{ }
public TestClass(int test) // EOL comment on ConstructorDecl
// Comment on ConstructorInitializer
: this("test") // EOL comment on ConstructorInitializer
{ }
// Destructor
~TestClass()
{ }
public void Dispose()
{ }
// PROPERTIES
/// <summary>
/// Test property.
/// </summary>
/// <value>This is a test value.</value>
[Custom] // property attribute
public string Test
{
get { return /*inline*/ _test; } // getter
[Custom]
protected set { _test = value; /* EOL comment */ } // setter
}
// INDEXERS
/// <summary>
/// This is an indexer.
/// </summary>
/// <param name="p1">First parameter <c>p1</c>.</param>
/// <param name="p2">Second parameter <paramref name="p2"/>.</param>
/// <returns>Double result.</returns>
[Custom] // indexer attribute
public double this[int p1, int p2]
{
get { return _2darray[p1, p2]; }
[Custom]
private set { _2darray[p1, p2] = value; }
}
// DELEGATES
delegate void VoidNoParms();
public delegate void VoidString(string msg);
public delegate void VoidTwoParms(double p1, double p2);
public delegate string StringTwoParms(ref string p1, out double p2);
private delegate int GenericIntParamsT<T>(params T[] p1) where T : struct;
private VoidNoParms _del1 = new VoidNoParms(Console.WriteLine);
private VoidTwoParms _del2 = _instance.MethodVoid2;
private StringTwoParms _del3 = _instance.MethodString;
private GenericIntParamsT<int> _del4 = _instance.MethodInt;
private VoidNoParms _adel1 = delegate { int i = 2; };
private GenericIntParamsT<int> _adel2 = delegate(int[] ai) // EOL comment
{
return ai.Length;
};
public static VoidString WriteLine = new VoidString(Console.WriteLine);
private static void MethodWithDelegateParameter(string s, VoidNoParms del)
{
del();
}
private static void MethodWithDelegateParameter(string s, VoidTwoParms del)
{
del(1.0, 2.0);
}
private static string MethodWithDelegateParameter3(string s, GenericIntParamsT<int> del)
{
return (s + del(1, 2));
}
private static string MethodWithDelegateParameter4(string s, Func<IEnumerable<double>, string> del)
{
return null;
}
public void TestDelegates()
{
MethodWithDelegateParameter("1a", delegate() { Console.WriteLine(); });
MethodWithDelegateParameter("1b", Console.WriteLine);
MethodWithDelegateParameter("1c", Generic<int>);
MethodWithDelegateParameter("2a", delegate(double a, double b) { a = b; });
MethodWithDelegateParameter3("3a", delegate { return 1; });
MethodWithDelegateParameter3("3b", delegate(int[] ai) { return ai.Length; });
MethodWithDelegateParameter4("4a", string.Concat<double>);
Action<double, double> dela = delegate(double s1, double s2) { string.Concat(s1, s2); };
MethodWithDelegateParameter("1a", new VoidTwoParms(dela));
Func<int[], int> func1b = MethodInt;
}
public void Generic<T>()
{ }
// EVENTS
event VoidNoParms _event1 = null, _event2 = MethodVoid1; // field-like events
// This is an event
[Custom] // event attribute
event VoidNoParms Event2
{
[Custom]
add { _event1 += value; } // adder
remove { _event1 -= value; } // remover
}
// OPERATOR OVERLOADING
public static int operator +(TestClass p) { return 0; } // unary
public static int operator +(TestClass left, int right) { return 0; } // binary
public static implicit operator string(TestClass p) { return null; } // implicit conversion
public static explicit operator double(TestClass p) { return 0; } // explicit conversion
public static void OperatorOverloading()
{
DateTime dt1 = DateTime.Now;
TimeSpan diff = DateTime.Now - dt1;
dt1 += diff;
dt1.ToString();
TestClass t = new TestClass();
int i = t + 5;
string s = t + " " + t;
int.Parse(t);
double d = (double)t;
}
// Main Testing Method
[Conditional("DEBUG"),
Conditional("TRACE")] // method attributes
[Obsolete("Use new method", true)]
void MethodTest()
{
// ----- TYPES -----
// (using Variables and Literals to test)
object uo; // uninitialized
object o = null; // null Literal
bool b1 = true; // true Literal
bool b2 = false; // false Literal
byte b = 255;
sbyte sb = -128;
short s = -32768;
ushort us = 65535;
int i = -2147483648;
uint ui = 4294967295;
long l = -9223372036854775808l;
ulong ul = 18446744073709551615L;
float f1 = 3.4e38f;
float f2 = -1.5e-45F;
double d1 = 1.7e308d;
double d2 = -5.0e-324D;
double NegativeInfinity = -1.0 / 0.0;
double PositiveInfinity = 1.0 / 0.0;
double NaN = 0.0 / 0.0;
decimal m = 1000000m;
char c1 = 'a';
char c2 = '\\';
string s1 = null;
string s2 = "\\";
string s3 = "test";
// enums
E1 e1 = (E1)0;
E1 e2 = E1.Two;
TestEnum e3 = TestEnum.One | TestEnum.Two | _testEnum;
// Arrays (simple)
int[] ia = { 1, 2, 3, i + 2 };
char[] cha = { ' ', '\'', '"', '\n', '\xffff', (char)(c1 + 2) };
string[] sa = { "one", "two", s3 + "val" };
int[] ia2 = new int[2] { 1, 2 };
// Multi-dimensional Arrays
double[,] dax2 = { { 1, 2 }, { 3, 4 } };
double[,] dax2b = new double[2, 2] { { 1, 2 }, { 3, 4 } };
// Jagged Arrays
int[][] ijax2 = new int[2][] { new int[] { 1 }, new int[2] { 21, 22 } };
Test.Full.TestClass[][] ijau = new Test.Full.TestClass[1][];
int[][,] ijax3 = new int[][,] { new int[,] { { 1 }, { 2 } } };
// Generic Types
System.Collections.Generic.List<int> li = new List<int>();
List<List<int>> lli = new List<List<int>>();
// Nullable Types
int? ni = (int?)i;
System.DateTime? ndt = new System.DateTime?();
int? ni2 = null;
Test.Full.TestStruct? ns = null;
// const
const int ci = -1;
const long cl = E + ci;
const uint cui = 1;
long csum = cui + ci;
const string cs1 = " This string has a \n\"linefeed\" in it ";
const string cs2 = @"LF esc: \n, double quote: """;
const string cs3 = "Escapes: \\\'\"\0\a\b\f\n\r\t\v\x0a\x7f\u2425\U0010FFFF";
const string cs4 = cs2 + cs3;
string test = cs4 + " " + cl;
// Use of namespace and type aliases
Win.Clipboard.Clear();
App.Current.ToString();
App app = new App();
// Hex literals
b = 0xff;
sb = 0x7f;
s = 0x7FFF;
us = 0xFFFF;
i = 0x7fffffff;
ui = 0xffffffff;
l = 0x7fffffffffffffff;
ul = 0xffffffffffffffff;
c1 = (char)0x0041;
// ----- OPERATORS -----
// UNARY OPERATORS
b1 = !b2; // Not
i = ~i; // Complement
i = +i; // Positive
i = -i; // Negative
++i; // Increment
--i; // Decrement
i++; // PostIncrement
i--; // PostDecrement
b = (byte)i; // Cast
// BINARY OPERATORS
i = 1; // Assignment
i = i + 1; // Add
i = i - 1; // Subtract
i = i * 1; // Multiply
i = i / 1; // Divide
i = i % 1; // Mod
i = i & 1; // BitwiseAnd
i = i | 1; // BitwiseOr
i = i ^ 1; // BitwiseXor
b1 = (b1 && b2); // And
b1 = (b1 || b2); // Or
b1 = (i == 1); // Equal
b1 = (i != 1); // NotEqual
b1 = (i < 1); // LessThan
b1 = (i > 1); // GreaterThan
b1 = (i <= 1); // LessThanEqual
b1 = (i >= 1); // GreaterThanEqual
i = (i << 1); // LeftShift
i = (i >> 1); // RightShift
i += 1; // AddAssign
i -= 1; // SubtractAssign
i *= 1; // MultiplyAssign
i /= 1; // DivideAssign
i %= 1; // ModAssign
i &= 1; // BitwiseAndAssign
i |= 1; // BitwiseOrAssign
i ^= 1; // BitwiseXorAssign
i <<= 1; // LeftShiftAssign
i >>= 1; // RightShiftAssign
s1 = (s2 ?? ""); // IfNullThen
// OTHER OPERATORS
MethodVoid1(); // Call (static)
_instance.MethodVoid2(1, 2); // Call (instance)
ia[0] = 0; // Index
o = (b1 ? new Dictionary<int, string>() : null); // Conditional
s1 = ((object)o).ToString(); // Dot
s1 = (o as string); // As
b1 = (o is int); // Is
Type t = typeof(Dictionary<,>); // TypeOf
i = sizeof(int); // SizeOf
i = checked(++i); // Checked
i = unchecked(++i); // Unchecked
i = new int(); // New simple type
o = new Test.Full.TestClass("test"); // New class
o = new TestStruct(); // New struct
PlatformID p = global::System.PlatformID.Win32NT; // Lookup
// This can be used to test loading of private types from referenced assemblies
//System.Web.DataAccess.SqlConnectionHelper h;
// ----- EXPRESSIONS -----
// (see above for Variables & Literals, including const, null, true, false)
// Compound Variable Declarations
int mi1, mi2 = 2, // Number 2
mi3; // Third one
// Parenthesis Usage
b1 = ((b1 && b2) || (i > 0)); // Nested parens
i = i - (1 + 2); // Necessary parens
i = -(i + 1); // Unary operator w/necessary parens
i = ((i + 1) + 2) + 3; // Unnecessary parens: ((i + 1) + 2) + 3
i = (i + 1) + (2 + 3); // Necessary parens: (i + 1) + (2 + 3)
i = i + (1 + (2 + 3)); // Necessary parens: i + (1 + (2 + 3))
// Stand-alone code block
{ // Infix EOL comment
// This & Base usage
o = this; // this
this.MethodVoid2(1, 2); // this scope
d1 = this[0, 0]; // this indexer
base.GetType(); // base scope
o = base[0]; // base indexer
}
// Multiple statements on the same line
s3 = s1; s1 = s2; s2 = s3; // Swap s1 and s2
// ----- STATEMENTS -----
// IF
// empty statement
if (i == 1)
; // empty
// single statement
if (i == 1)
i = 2;
// single statement, same line
if (i == 2) i = 1; // single line 'if'
// block
if (i == 1) { // K&R style
i = 2;
b1 = true;
}
// IF / ELSE
// empty statement
if (i == 1)
;
else
;
// single statement
if (i == 1)
i = 2;
else
i = 1;
// block
if (i == 1)
{
i = 2;
b1 = true;
}
else
{
i = 1;
b1 = true;
}
// IF / ELSE CHAINING
// WITHOUT else-if chaining
if (i == 1)
;
// else comment
else
{
// if comment
if (i == 2)
{
i = 1;
b1 = true;
}
else // else EOL comment
{
if (i == 3) // if EOL comment
i = 2;
else
i = 0;
}
}
// WITH else-if chaining
if (i == 1)
;
// else-if comment
else if (i == 2)
{
i = 1;
b1 = true;
}
else if (i == 3) // else-if EOL comment
i = 2;
else
i = 0;
// SWITCH / CASE / DEFAULT
// empty switch
switch (i)
{
}
// single case
switch (i)
{
case 1:
b1 = true;
break;
}
// multiple case, default
switch (i)
{
case 1: // empty case fall-through
case 2:
// Comment inside brace-less block
b1 = true;
break;
// This case has braces for scope
case 3:
// Comment outside block after header
{
int a = i;
if (a == 1)
break;
b2 = true;
break;
}
// This is the default case
default:
b1 = b2 = false;
break;
}
// GOTO
Label1: // first label
Label2: // another label
switch (i)
{
case 1:
goto Label1; // goto label
case 2:
goto case (int)(1L * 2); // goto case
case 3:
goto default; // goto default
default:
break;
}
// WHILE
// null body
while (i < 100);
// empty statement
while (i < 100)
;
// single statement
while (i < 100)
++i;
// block
while (i < 100)
{
++i;
continue;
}
// do infinite loop
while (true)
{
++i;
if (i > 100) break;
}
// DO / WHILE
// empty statement
do
;
while (i < 100);
// single statement
do
++i;
while (i < 100);
// block
do
{
++i;
b1 = true;
}
while (i < 100);
// FOR
// null body
for (i = 0; i < 100; /*infix*/);
// empty statement
for (i = 0; i < 100; ++i)
;
// single statement
for (int i1 = 0, i2 = 0; i1 < 100; ++i1, --i2)
i += i1;
// block
for (i = 0, l = 0; i < 100; ++i, --l)
{
l += i;
b1 = true;
}
// do infinite loop
for ( ; ; )
break;
// FOREACH
// empty statement
foreach (int v in ia)
;
// single statement
foreach (int v in ia)
i += v;
// block
foreach (int v in ia)
{
i += v;
b1 = true;
}
// ----- EXCEPTIONS -----
try // try
{
++i;
}
catch (OverflowException) // catch w/o variable
{
throw; // re-throw
}
catch (StackOverflowException ex) // catch w/variable
{
throw ex; // new throw
}
catch // catch all exceptions
{ }
finally // finally
{
b2 = true;
}
using (_instance) // expression
{
}
using (Test.Full.TestClass obj = new TestClass()) // local variable
{
}
using (TestClass obj1 = new TestClass(), obj2 = new TestClass()) // multiple variables
{
}
using (TestClass obj1 = new TestClass()) // multiple nested usings
using (TestClass obj2 = new TestClass()) // (should display at the same indent level,
using (TestClass obj3 = new TestClass()) // and only have braces on the inner-most block)
{
}
// ----- LOCK -----
// empty statement
lock (o)
;
// single statement
lock (o)
++i;
// block
lock (o)
{
++i;
b1 = true;
}
// ----- METHODS -----
i = MethodInt(1);
if (MethodString(/* inline, */ ref s3, out d1) == null)
i = MethodGeneric<int, object>(o);
ia = MethodGeneric2(i);
MethodUIntULong(1u + 1, 1ul - 1);
MethodUIntULong(ui + 1, ul - 1);
decimal.Round(b1 ? ci : 100m);
string.Format("{0} {1}", 1, int.MaxValue);
string.Format("{0} {1} {2} {3}", 1, int.MaxValue, 2d, 3f);
string.Format("");
li.Add(1);
_del1();
s1 = _del3(ref s2, out d1);
i = _del4(1);
_del1 += MethodVoid1;
// ----- PROPERTIES -----
s1 = Test;
Test = s1;
// ----- INDEXERS -----
d1 = _instance[0, 0];
_instance[0, 0] = d1;
// ----- EVENTS -----
Event2 += MethodVoid1;
// ----- COMMENTS -----
// This is an independent comment that is split...
//
// across 3 lines.
// This comment is associated with the statement below
// This is a separate comment associated with the statement below, and
// it spans two lines.
i = 1; // This EOL comment is associated with the statement on the left
b1 = ((b1 && b2) /* embedded comment */ || !(i > 0)); // EOL comment
if ((s != null) // EOL on !=
&& (this.Capacity > 0) // EOL on '&&' #1
&& System.Console.CursorVisible // EOL on '&&' #2
// Postfix comment
)
{
b1 = ((b1 // EOL on b1
&& ((long)System.Console.BufferWidth // EOL on cast
> 0) // EOL on '>'
// Postfix comment on '>'
) // EOL on '&&'
|| // EOL on ||
!(i < 0 // EOL on '0'
) // EOL on '!'
);
object[] objs = new object[]
{
this.Capacity, // 1st
(long)Console.BufferWidth, // 2nd
(b1 && b2) || (i == 0), // 3rd
s // 4th
};
int i1 = 1, // 1
i2 = 2, // 2
i3 = (int)Console.BufferWidth; // 3
}
// There is a triple blank line after this comment...
/* Block comment Line 1
* Line 2 */
/* Block comment Line 1
* Line 2
* Line 3
*/
// TODO: This is a 'to-do' comment
// ----- COMPILER DIRECTIVES -----
#region /* COMPILER DIRECTIVES */
// See top of file for #define/#undef examples, since they can only legally appear there
#if (TEST1 && TEST2 && TEST3) || !TEST4 || ((TEST5 == true) && (TEST6 != false)) // comment
#if TEST1 // conditional compilation
// This 'code' will not be compiled:
It's not actually code, but that doesn't matter.
#elif TEST2 // elif
This text won't be compiled.
#else // else
#warning Warning message!
//#error Error message!
#line 999 "C:\path\test.cs" // comment
#line hidden // comment
#line default // comment
#endif // endif
#endif
string[] cds =
{ // EOL comment
// Regular comment
"one",
#if false
"too",
#else
// Regular comment
"two" // EOL comment
#endif
#if false
"three"
#endif
};
#pragma warning disable // comment
#pragma warning restore // comment
#pragma warning disable 78, 219, 1691 // comment
#pragma warning restore 78, 219, 1691 // comment
#pragma warning disable
#pragma checksum "test.cs" "{00000000-0000-0000-0000-000000000000}" "01234567" // comment
#endregion /* COMPILER DIRECTIVES */
}
// ----- OTHER METHODS -----
static void MethodVoid1(/*infix*/) // No parameters, empty body, static
{ }
new void MethodVoid2(double p1, double p2) // Two parameters
{
return; // Return with no value
}
void MethodUIntULong(uint p1, ulong p2)
{ }
/// <summary>
/// Test method with <b>one</b> parameter.
/// The <paramref name="pa"/> parameter is an <i>optional</i> list of <c>int</c>.
/// Use standard XML escapes to embed chars such as: < & >
/// <para>2nd paragraph</para>
/// <see cref="string.IndexOf"/>
/// <seealso cref="MethodString(ref string, out double)"/>
/// Generics can be referenced like <see cref="List{T}"/>.
/// </summary>
/// <param name="pa"></param>
/// <returns>The result.</returns>
/// <exception cref="System.Exception">Thrown when...</exception>
/// <permission cref="System.Security.PermissionSet">Everyone can access this method.</permission>
/// <remarks>
/// This is the remarks section.
/// <see cref="System.Threading.Monitor.Enter(object, ref bool)"/>
/// Here is a list:
/// <list type="bullet">
/// <listheader>
/// <term>Header Term</term>
/// <description>Header Description</description>
/// </listheader>
/// <item>
/// <term>Term 1</term>
/// <description>Description 1.</description>
/// </item>
/// <item>
/// <term>Term 2</term>
/// <description>Description 2.</description>
/// </item>
/// </list>
/// </remarks>
/// <example>This example shows how to call the <see cref="MethodInt"/> method.
/// <code>
/// int result = MethodInt(10);
/// List{int} list = new List<int>();
/// bool b = (result & 0x80) <= 3;
/// object o = list[0];
/// int i = MethodGeneric{int, object}(o);
/// string s = "<&>";
/// if (b)
/// {
/// if (result > 0)
/// Console.WriteLine("");
/// }
/// </code>
/// </example>
int MethodInt(/*inline*/ params int[] pa) // One parameter
{
return (pa[0] * -1); // Return a value
}
string MethodString(ref string p1,
out double p2) // Two parameters
{
p2 = 0;
return p1;
}
/// <summary>
/// Generic method.
/// </summary>
/// <typeparam name="T">Type parameter T.</typeparam>
/// <typeparam name="U">Type parameter U.</typeparam>
/// <param name="u">Parameter u.</param>
/// <returns>Result T.</returns>
T MethodGeneric<T, U>(U u) // EOL comment on GenericMethodDecl
where T : U // EOL comment on 1st constraint
where U : class // EOL comment on 2nd constraint
{
return ((u == null) ? default(T) : (T)u);
}
new T[] MethodGeneric2<T>(T obj)
{
return new T[1];
}
public IEnumerator<int> GetEnumerator() // Iterator
{
yield return 1;
yield return 2;
yield break;
}
[DllImport("kernel32", SetLastError = true, ExactSpelling = true)]
static extern bool RemoveDirectory(string name); // extern - no body
void AMethod([In, Out] ref double x) // parameter attributes
{ }
// This is a nested, generic interface
interface InnerInterface<T>
{
void Method();
string Property { get; set; }
T this[T i] { get; }
event VoidNoParms Event;
}
/// <summary>
/// This is a nested, generic class.
/// </summary>
/// <typeparam name="T">Type parameter T.</typeparam>
/// <typeparam name="U">Type parameter U.</typeparam>
class InnerClass<T, U> // EOL comment on ClassDecl
// Comment on base-type list
: InnerInterface<T> // EOL comment on base type/interface
// Comment on constraints
where T : struct where U : TestClass, new() // EOL comment on constraints
{
protected T t;
public U u;
public InnerInterface<T> p;
private static readonly InnerClass<int, TestClass> _instance;
private Inner2<long> _inner2;
// Static constructor
static InnerClass()
{
_instance = new InnerClass<int, TestClass>();
Type t1 = ((InnerInterface<T>)_instance).GetType();
Type t2 = ((IList)new List<T>()).GetType();
_instance._inner2 = new InnerClass<int, TestClass>.Inner2<long>();
string s = _instance._inner2.Inner2Generic(1, TestClass._instance, 2L, TestClass._instance);
}
// Explicit interface implementations
void InnerInterface<T>.Method() { }
string InnerInterface<T>.Property { get { return ""; } set { } }
T InnerInterface<T>.this[T i] { get { return default(T); } }
event VoidNoParms InnerInterface<T>.Event { add { } remove { } }
/// <summary>
/// Nested, generic type, with generic method referencing parent type parameters.
/// </summary>
/// <typeparam name="V">Type parameter V.</typeparam>
private class Inner2<V> where V : IComparable
{
/// <summary>
/// Inner2Generic test method.
/// This method has generic parameter <typeparamref name="W"/>.
/// </summary>
/// <typeparam name="W">Type parameter W.</typeparam>
/// <param name="t">Parameter t.</param>
/// <param name="u">Parameter u.</param>
/// <param name="v">Parameter v.</param>
/// <param name="w">Parameter w.</param>
/// <returns>String result.</returns>
public string Inner2Generic<W>(T t, U u, V v, W w) where W : U
{
return (t.ToString() + u + v + w);
}
}
}
/// <summary>
/// This is a nested struct, generic on <typeparamref name="T"/>.
/// </summary>
/// <typeparam name="T">Type parameter.</typeparam>
public struct InnerStruct<T>
{
}
class InnerDerived : InnerClass<DateTime, TestClass>
{
void Method()
{
int v = t.Hour;
}
}
class TestCollection<TItem> : List<TItem>
{
}
void CollectionMethod(List<TestClass> list)
{ }
void TestGenericCollection()
{
TestCollection<TestClass> collection = new TestCollection<TestClass>();
CollectionMethod(collection);
}
public class TestBase<T>
{
private T t = default(T);
public T Property { get { return t; } }
}
public class InnerTest : TestBase<TestClass>
{
public void Test()
{
string s1 = Property.Test;
}
}
}
// This is a top-level interface
public interface ITestInterface : IComparable
{
}
/// <summary>
/// This is a top-level struct
/// </summary>
public struct TestStruct
{
}
}