推断方法-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 类型已知)。
我有一个通用基础 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 类型已知)。