Вывести тип возвращаемого метода, который является общим c типом другого типа - PullRequest
2 голосов
/ 07 мая 2020

У меня есть общий c базовый класс с одной реализацией:

public abstract class Setting<T> : ISetting
{
    public T DefaultValue { get; }
}

public class SubscribeToNewsletterSetting : Setting<bool>
{
   ...
}

Теперь у меня есть класс настроек, использующий следующие настройки:

public class UserSettings
{
    public TSetting GetSetting<TSetting>(int ownerId)
        where TSetting : ISetting
    {
        ....
    }
}

Теперь Я могу использовать класс UserSettings следующим образом:

var setting = settings.GetSetting<SubscribeToNewsletterSetting>(22);
var settingsValue = setting.DefaultValue;

Теперь мне было интересно - можно ли сделать это за один шаг, без указания типа: например:

var settingsValue = settings.GetSettingDefaultValue<SubscribeToNewsletterSetting>(22);

(Не хочу так называть)

var settingsValue = settings.GetSettingDefaultValue<SubscribeToNewsletterSetting, bool>(22);

Ура, Мануэль

Ответы [ 2 ]

1 голос
/ 07 мая 2020

К сожалению, это невозможно. Вывод типа параметров generi c - это предложение "все или ничего". Либо все параметры могут быть выведены, и вы должны (явно) не указать ни одного, либо вы должны указать их все явно.

У вас есть выбор только между следующими вариантами:

public class UserSettings
{

    // Variant A
    public TSetting GetSetting<TSetting>(int ownerId)
        where TSetting : ISetting
    {
        return default;
    }

    // Variant B
    public TValue GetSettingValue<TSetting, TValue>(int ownerId)
        where TSetting : Setting<TValue>
    {
        return default;
    }
}

Что вы можете использовать вот так. Где x,y,z должны быть неявно набраны как bool.

class Demo
{
    public void Run()
    {
        var us = new UserSettings();

        // Variant A
        var x = us.GetSetting<SubscribeToNewsletterSetting>(22).DefaultValue;

        // Variant B 
        var y = us.GetSettingValue<SubscribeToNewsletterSetting, bool>(22);

        // desired, but impossible
        var z = us.GetSettingValue<SubscribeToNewsletterSetting>(22);
    }
}

Я рекомендую добавить свойство public T Value {get;} в Settings<T> и добавить код доступа к базе данных (или по крайней мере, в части строгой типизации) на 'SubscribeToNewsletterSetting' (где известен тип TValue).

0 голосов
/ 07 мая 2020

, если я правильно понял вопрос, вы хотите рассматривать экземпляр SubscribeToNewsletterSetting также как значение boolean, если да ... тогда вы можете сделать следующее:

    public abstract class Setting<T>
    {
        public T DefaultValue { get; }

        public static implicit operator T(Setting<T> value)
        {
            return value.DefaultValue;
        }
    }

    public class SubscribeToNewsletterSetting : Setting<bool>
    {
    }


    public static async Task Main()
    {
        ...
        // Will work fine.
        bool isEnabled = settings.GetSetting<SubscribeToNewsletterSetting>(22);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...