using System; using System.Text; class CustomMatrix where MATRIX : CustomMatrix { public readonly uint sizeY, sizeX; public readonly ELEM[,] data; protected CustomMatrix(uint sizeY, uint sizeX) { this.sizeY = sizeY; this.sizeX = sizeX; data = new ELEM[sizeY, sizeX]; } protected CustomMatrix(uint sizeY, uint sizeX, Func get) : this(sizeY, sizeX) { for (uint y = 0; y < sizeY; y++) for (uint x = 0; x < sizeX; x++) data[y, x] = get(y, x); } public MATRIX Transpose() { Func transposer = (y, x) => data[x, y]; return (MATRIX)Activator.CreateInstance( typeof(MATRIX), new object[]{ sizeX, sizeY, transposer }); } public ELEM this[uint y, uint x] { get { return data[y, x]; } set { data[y, x] = value; } } public override string ToString() { var sb = new StringBuilder(); for (uint y = 0; y < sizeY; y++) { if (y > 0) sb.Append("\n"); for (uint x = 0; x < sizeX; x++) { if (x > 0) sb.Append(" "); sb.Append(data[y, x]); } } return sb.ToString(); } } class Matrix : CustomMatrix> { public Matrix(uint sizeY, uint sizeX) : base(sizeY, sizeX) { } public Matrix(uint sizeY, uint sizeX, Func get) : base(sizeY, sizeX, get) { } public static explicit operator SquareMatrix(Matrix m) { return new SquareMatrix(m.sizeY, m.sizeX, (y, x) => m[y, x]); } } class SquareMatrix : CustomMatrix> { public SquareMatrix(uint size) : base(size, size) { } public SquareMatrix(uint size, Func get) : base(size, size, get) { } public SquareMatrix(uint sizeY, uint sizeX, Func get) : base(sizeY, sizeX, get) { if (sizeY != sizeX) throw new ArgumentException(string.Format("SquareMatrix не может быть размера {0}×{1}.", sizeY, sizeX)); } public static explicit operator Matrix(SquareMatrix m) { return new Matrix(m.sizeY, m.sizeX, (y, x) => m[y, x]); } } public class MainClass { public static void Main() { Matrix m = new Matrix(3, 5, (y, x) => 2*y + x); Console.WriteLine("m: Matrix =\n{0}", m); Matrix m_t = m.Transpose(); Console.WriteLine("\nm.Transpose() =\n{0}", m_t); string m_as_sm_s; try { m_as_sm_s = ((SquareMatrix)m).ToString(); } catch (ArgumentException e) { m_as_sm_s = e.Message; } Console.WriteLine("\n(SquareMatrix) m =\n{0}", m_as_sm_s); SquareMatrix sm = new SquareMatrix(5, (y, x) => 5 + (int)x - (int)y); Console.WriteLine("\nsm: SquareMatrix =\n{0}", sm); SquareMatrix sm_t = sm.Transpose(); Console.WriteLine("\nsm.Transpose() =\n{0}", sm_t); Matrix sm_as_m = (Matrix)sm; Console.WriteLine("\n(Matrix) sm =\n{0}", sm_as_m); SquareMatrix sm_as_m_as_sm = (SquareMatrix)sm_as_m; Console.WriteLine("\n(SquareMatrix) (Matrix) sm =\n{0}", sm_as_m_as_sm); } }