仅限制 DTO 模型的通用方法(class & 记录)
Restrict generic method for DTO models only (class & record)
非常简单的问题。我只想在输入中允许 DTO 模型(class 和记录类型)。
如果我只保留 class
约束,我仍然可以将 string
放在那里。我不想允许原始类型。
如果我输入 class, new()
,它不允许 string
正如预期的那样,但我也不允许使用位置记录,这是一个问题。
public class Asd
{
public string Name { get; set; }
}
public record Asd2(string Name);
public Task DoSomethingAsync<TInput>(TInput data) where TInput : class
{
var message = JsonSerializer.Serialize(data); // if TInput is a string, it results into faulty \u0022 codes
}
Edit:实际问题是我在该方法中有 JsonSerializer.Serialize(data)
,如果 string
被意外传递,它会导致类似:
"{\u0022Name\u0022:\u0022Test\u0022}"
您需要对限制具有某种共性。
这需要是公共基础 class 或接口。
既然你也想用Records,那么这肯定是一个接口。但是如果您只是为了这个目的,您可以只定义一个简单的空的。
所以你定义了一个简单的空接口(如果你真的有一些通用的更好functions/properties)。
public interface MyInterface
{
}
所以你的代码看起来像这样
public Task DoSomethingAsync<TInput>(TInput data) where TInput : MyInterface
{
}
你所有的 classes 和记录都是这样继承的。
public record AsdRecord: MyInterface
{
//details here
}
public class AsdClass: MyInterface
{
//details here
}
如果您的允许类型列表不能用类型约束来制定,请考虑创建一个允许类型列表(在代码中硬编码或在运行时使用反射,例如在命名空间上)并在运行时针对该列表进行测试就在方法的开头(就像您还测试传入参数一样)。也许是这样的
private static readonly HashSet<Type> AllowedTypes = new HashSet<Type>
{
typeof(MyTypeA),
typeof(MyTypeB),
};
public Task DoSomethingAsync<TInput>(TInput data)
{
if(!AllowedTypes.Contains(typeof(TInput)))
throw new ArgumentException($"The type {typeof(TInput).Name} can' t be used here.");
// ...
}
虽然这在编译时对您没有帮助,但至少在运行时对您有帮助。
非常简单的问题。我只想在输入中允许 DTO 模型(class 和记录类型)。
如果我只保留 class
约束,我仍然可以将 string
放在那里。我不想允许原始类型。
如果我输入 class, new()
,它不允许 string
正如预期的那样,但我也不允许使用位置记录,这是一个问题。
public class Asd
{
public string Name { get; set; }
}
public record Asd2(string Name);
public Task DoSomethingAsync<TInput>(TInput data) where TInput : class
{
var message = JsonSerializer.Serialize(data); // if TInput is a string, it results into faulty \u0022 codes
}
Edit:实际问题是我在该方法中有 JsonSerializer.Serialize(data)
,如果 string
被意外传递,它会导致类似:
"{\u0022Name\u0022:\u0022Test\u0022}"
您需要对限制具有某种共性。 这需要是公共基础 class 或接口。
既然你也想用Records,那么这肯定是一个接口。但是如果您只是为了这个目的,您可以只定义一个简单的空的。
所以你定义了一个简单的空接口(如果你真的有一些通用的更好functions/properties)。
public interface MyInterface
{
}
所以你的代码看起来像这样
public Task DoSomethingAsync<TInput>(TInput data) where TInput : MyInterface
{
}
你所有的 classes 和记录都是这样继承的。
public record AsdRecord: MyInterface
{
//details here
}
public class AsdClass: MyInterface
{
//details here
}
如果您的允许类型列表不能用类型约束来制定,请考虑创建一个允许类型列表(在代码中硬编码或在运行时使用反射,例如在命名空间上)并在运行时针对该列表进行测试就在方法的开头(就像您还测试传入参数一样)。也许是这样的
private static readonly HashSet<Type> AllowedTypes = new HashSet<Type>
{
typeof(MyTypeA),
typeof(MyTypeB),
};
public Task DoSomethingAsync<TInput>(TInput data)
{
if(!AllowedTypes.Contains(typeof(TInput)))
throw new ArgumentException($"The type {typeof(TInput).Name} can' t be used here.");
// ...
}
虽然这在编译时对您没有帮助,但至少在运行时对您有帮助。