Homework - как да избегнем dynamic


3

 public static Matrix<T> operator -(Matrix<T> m1, Matrix<T> m2)
        {
            if (m1.Rows != m2.Rows || m1.Columns != m2.Columns)
            {

                throw new ArgumentOutOfRangeException("The both of the matrices have to have same dimensions");
            }
            Matrix<T> result = new Matrix<T>(m1.Rows, m2.Columns);
            for (int i = 0; i < m1.Rows; i++)
            {
                for (int j = 0; j < m1.Columns; j++)
                {
                    result[i, j] = (dynamic)m1[i, j] - m2[i, j];
                }
            }
            return result;

        }

Имам overload на този оператор. Знае ли някой как да избегнем това dynamic " (dynamic)m1[i, j] - m2[i, j];" и да работи? :)




Отговори



5
За съжаление лесен начин няма - това дори е доста популярен feature request за C# - да могат да се ограничат generics до само типове, с които може да се пресмята. Остави го така, това е пример, в който dynamic е "почти" полезен. Казвам почти, защото класа Matrix няма да работи с нещо, което не разбира от изваждане. Можеш да направиш проверка дали типа може да бъде изваден с if (typeof(T) != typeof(Int32)) (както и всички останали типове данни) и да хвърлиш exception, че операцията изваждане не е позволена. Тази проверка е хубаво да бъде в отделен метод някъде в проекта.

от ivaylo.kenov (30760 точки)


1

Може да изполваш Reflection. Нещо от рода на:

                Type type = typeof(T);
                 double valueA = double.Parse(matrixA[row, col].ToString());
                 double valueB = double.Parse(matrixB[row, col].ToString());
                 object result = (object)(valueA + valueB);

                  resultMatrix[row, col] = (T)Convert.ChangeType(result, type);

Но като цяло ако избора трябва да е reflection vs dynamic май по-добре да си го направиш с dynamic.

И в двата случая ако ти подадът не числен тип и тръгнеш да умножаваш матриците ще си гръмне като коледна заря.


от wnvko (3123 точки)


1

 Аз просто пуснах една проверка в конструктора ако не е някой от числените типове да хвърли еxception. После обаче в аритметиката ги каствам към object и обратно, след като вече съм се убедил че са някакъв числен тип.

 Бях доста потресен след час ровене из стак-а, като разбрах че няма констрейн за числени типове.


от ivan.mihov1 (4988 точки)


1
Да определено е гадно да откриеш, че няма нещо, в което си бил 1000% процента сигурен, че съществува и че просто ти убягва някак си. Дано да го имплементират някак си тоя констрейн за числените типове. Ще е просто чудесно :)

от wnvko (3123 точки)

0
 Да ти кажа не се оплаквам много от такива неща, защото откакто започнах да работя с .NET 3.5 разбрах какво е нямане :D

от ivan.mihov1 (4988 точки)