Генеричният клас няма същия тип връщане като неговия интерфейс

Искам да имам общ клас за моята стойност на параметъра и да връщам съдържанието му с помощта на интерфейсен метод, но имам грешка при компилиране относно липсата на съвпадащ тип връщане. Има ли начин това да се поправи? Моят код по-долу:

    public class Parameter
    {
        public Parameter(String name, int value)
        {
            this.name = name;
            this.type = eType.typeInt;
            this.parameterValue = new ParameterValueTemplate<int>(value);
        }

        public Parameter(String name, double value)
        {
            this.name = name;
            this.type = eType.typeDouble;
            this.parameterValue = new ParameterValueTemplate<double>(value);
        }

        public interface IParameterValue
        {
            int GetValue();
        }

        class ParameterValueTemplate<T> : IParameterValue
        {
            public ParameterValueTemplate(T value)
            {
                this.value = value;
            }

            public T GetValue()
            {
                return value;
            }

            T value;
        }

        public String name;
        public IParameterValue parameterValue;
    }

person Pedro Ferreira    schedule 25.11.2014    source източник
comment
Вашият интерфейс също трябва да бъде общ. Вероятно се оплаква, защото изисквате int като тип на връщане от интерфейса за всеки общ шаблон за стойност на параметър.   -  person Vlad    schedule 25.11.2014
comment
Вашата декларация за клас е грешна за вашата употреба. Ако очаквате T да бъде IParameterValue, имате нужда от общо ограничение за T, а не за внедряване на интерфейса във вашия общ клас.   -  person Preston Guillot    schedule 25.11.2014
comment
уф Защо изобщо бихте вложили интерфейс. Това напълно обезсмисля смисъла на интерфейса!   -  person BradleyDotNET    schedule 25.11.2014
comment
@BradleyDotNET, съгласен съм, това вероятно е, защото той е виждал хора да конструират с интерфейси за DI и разрешаващи цели.. това обаче проваля целта тук.   -  person Brett Caswell    schedule 25.11.2014
comment
Да, предполагам, че си прав. Исках да факторизирам кода в общ клас и да не се налага да пиша имплементация за всеки тип стойност в моя параметър. Но предполагам, че ще трябва да го направя, да напиша производен клас за int, double и string.   -  person Pedro Ferreira    schedule 25.11.2014
comment
@BradleyDotNET, какво имаш предвид? Вложеният интерфейс е точно толкова полезен, колкото и невложеният, с изключение на това, че (може) да трябва да квалифицирате името му с Parameter.. Не казвам, че това е страхотна идея тук (или непременно навсякъде), но не съм сигурен в какъв смисъл напълно отхвърля смисъла на интерфейса. Можете ли да дадете пример, в който това нарушава целта на даден интерфейс?   -  person Kirk Woll    schedule 25.11.2014
comment
@KirkWoll Един интерфейс излага договор на външния свят, така че чрез влагането му той вече е част от Parameter обект. Как това има някакъв идиоматичен смисъл? (Разбира се, аз съм против вложените типове като цяло, така че мнението ми е доста пристрастно).   -  person BradleyDotNET    schedule 25.11.2014
comment
@BradleyDotNET, интерфейс излага договор -- вероятно на външния свят -- и вероятно на вашите собствени вътрешни класове на вашата библиотека. Може би сте донкихотовци и групирате куп свързани интерфейси в Interfaces клас. Аз не бих го препоръчал, но не променя семантиката, функционалността, поведението или честно казано нещо относно интерфейса или неговото изпълнение.   -  person Kirk Woll    schedule 25.11.2014
comment
@KirkWoll Напълно съм съгласен с теб. Предполагам, че искам да кажа, че не виждам разумна причина от реалния свят да правя това някога. Следователно; побеждавайки смисъла на интерфейс (може би недобре формулиран).   -  person BradleyDotNET    schedule 25.11.2014
comment
@BradleyDotNET, честно казано, приемам и мнението ти.   -  person Kirk Woll    schedule 25.11.2014
comment
@PedroNF: единственото нещо, което трябва да поправите тук, е да промените декларацията на интерфейса така, че да изглежда така -- public interface IParameterValue<T> { T GetValue(); } -- и след това да декларирате типа шаблон по този начин -- class ParameterValueTemplate<T> : IParameterValue<T>. Но от въпроса ви не става ясно кога това засяга някакъв по-широк проблем, който може да имате с дизайна тук.   -  person Peter Duniho    schedule 26.11.2014
comment
Искам да имам клас Parameter, който записвам в един речник‹String, Parameter›, така че не мога да имам Parameter като общ клас. Класът на параметъра се състои от име и стойност. Вътре в стойността мога да запазя int, double или String.   -  person Pedro Ferreira    schedule 26.11.2014
comment
@Peter Duniho: Ако интерфейсът е общ, тогава не мога да имам нито една ParameterValue в моя клас Parameter. Интерфейсът трябва да скрие типа на стойността.   -  person Pedro Ferreira    schedule 26.11.2014
comment
@PedroNF: Интерфейсът трябва да скрие типа на стойността -- дори като негенеричен, той не може да направи това. Или го правите общо, или избирате тип. Във всеки случай типът на стойността е известен. Единственият начин да пренебрегнете напълно типа на стойността е да използвате object като тип. Въпреки това нищо в моето предложение не изисква типът Parameter да бъде общ; само интерфейсът и внедряващият тип (който така или иначе вече сте направили общ).   -  person Peter Duniho    schedule 26.11.2014
comment
Чувствам, че този въпрос страда от XY проблема. Може би ако можете да обясните за каква цел се нуждаете от този тип функционалност, можете да получите по-добри отговори.   -  person Anthony    schedule 01.12.2014
comment
Не е ясно какво искате GetValue() да върне. Винаги int чрез преобразуване ли е, nullable ли е int, object или T каквото и да използва шаблонът?   -  person John Alexiou    schedule 01.12.2014
comment
Опитвате ли се да създадете препратка към тип стойност?   -  person John Alexiou    schedule 01.12.2014


Отговори (1)


Направих това по съвсем различен начин...! Исках да имам общ параметър клас, който може да съдържа различни типове стойности вътре, но останалата част от кода вече беше въведена, така че в крайна сметка използвах структура за съхранение и речник за бързо търсене на параметри по име :-)

person Pedro Ferreira    schedule 07.09.2015