推断方法-Return 类型是另一种类型的通用类型

Infer Method-Return Type which is generic type of another type

我有一个通用基础 class 和一个实现:

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

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

现在我有一个设置 class,使用这个设置:

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

现在我可以像这样使用 UserSettings class:

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

现在我想知道 - 是否可以在不指定类型的情况下一步完成此操作:例如:

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

(我不想这样称呼它)

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

干杯, 曼纽尔

如果我理解正确,你想将 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);
    }

很遗憾,这是不可能的。泛型参数的类型推断是一个全有或全无的命题。要么可以推断出所有参数并且您必须(明确地)指定 none,或者您必须明确地指定它们。

您只能在以下变体之间进行选择:

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 类型已知)。