C#泛型可以支持Class还是null?
在我当前的项目中,我有一个C#泛型可以支持Class还是null?,c#,generics,nullable,C#,Generics,Nullable,在我当前的项目中,我有一个值类 当前T可以是任何值,但我们必须支持Null值,因此当前我们以两种形式使用它: 值或值 我是否可以以任何方式创建一个值类,允许我指定Value或Value,但其效果是,对于类,值保持T,而对于结构,值保持T? 我们的目标是避免开发人员指定值之后出现问题,因为我们不能正确处理空值 Ie,我希望编译器支持避免错误 我是否可以以任何方式创建一个Value类,该类允许我指定Value或Value,但其效果是,对于类,值保持T,而对于结构,值保持T? 否,因为泛型类型约束中不
值
类
当前T
可以是任何值,但我们必须支持Null
值,因此当前我们以两种形式使用它:
值
或值
我是否可以以任何方式创建一个值类,允许我指定Value
或Value
,但其效果是,对于类,值保持T
,而对于结构,值保持T?
我们的目标是避免开发人员指定值
之后出现问题,因为我们不能正确处理空值
Ie,我希望编译器支持避免错误
我是否可以以任何方式创建一个Value
类,该类允许我指定Value
或Value
,但其效果是,对于类,值保持T
,而对于结构,值保持T?
否,因为泛型类型约束中不能有“或”逻辑
要在泛型类型约束中实现“或”逻辑,必须创建两个单独的泛型类,每个类都有自己的泛型类型约束。请注意,这两个类可以继承自一个完全没有类型约束的共享泛型基类。如果该基类型是抽象的,那么您可以确定使用者必须通过了派生类的类型约束检查(假设没有人添加其他派生类) 改变你的期望,而不是按照你现在想要的方式去做,会更合适 但我们必须支持
null
值
如果使用default(T)
,而不是null
,则问题得到解决
- 对于类类型,
有效地解析为default(MyClass)
null
- 对于结构,
返回一个其属性都包含默认值的结构default(MyStruct)
default(MyStruct)
是使用“可空性”概念而不必使用文本null
值的常用方法
用法示例:
public class Container<T>
{
private readonly Random _random = new Random();
public T DoSomething(T input)
{
//always returns "nothing"
return default(T);
}
}
public class MyClass
{
public int Value { get; set; }
}
public struct MyStruct
{
public int Value { get; set; }
}
public class Test
{
public bool ContainerReturnsNothing<T>(T input)
{
var container = new Container<T>();
var output = container.DoSomething(input);
return output.Equals(default(T));
}
public void TestAClassAndAStruct()
{
ContainerReturnsNothing(new MyClass() {Value = 1}); // true
ContainerReturnsNothing(new MyStruct() {Value = 1}); // true
}
}
将始终将default(MyStruct)
设置为IsConstructed
false
- 每个实例化的结构将始终将
设置为IsConstructed
true
var myStruct = new MyStruct(0);
var isNull = myStruct.Equals(default(MyStruct));
isNull
为false,因为myStruct
和default(myStruct)
为IsConstructed
包含不同的值(true
和false
)
如果使用原始示例中的MyStruct
类运行相同的检查,isNull
将为true,因为所有属性都匹配,即MyStruct
和default(MyStruct)
都将值设置为0
我是否可以以任何方式创建一个Value
类,该类允许我指定Value
或Value
,但其效果是,对于类,值保持T
,而对于结构,值保持T?
否,因为泛型类型约束中不能有“或”逻辑
要在泛型类型约束中实现“或”逻辑,必须创建两个单独的泛型类,每个类都有自己的泛型类型约束。请注意,这两个类可以继承自一个完全没有类型约束的共享泛型基类。
如果该基类型是抽象的,那么您可以确定使用者必须通过了派生类的类型约束检查(假设没有人添加其他派生类)
改变你的期望,而不是按照你现在想要的方式去做,会更合适
但我们必须支持null
值
如果使用default(T)
,而不是null
,则问题得到解决
- 对于类类型,
default(MyClass)
有效地解析为null
- 对于结构,
default(MyStruct)
返回一个其属性都包含默认值的结构
default(MyStruct)
是使用“可空性”概念而不必使用文本null
值的常用方法
用法示例:
public class Container<T>
{
private readonly Random _random = new Random();
public T DoSomething(T input)
{
//always returns "nothing"
return default(T);
}
}
public class MyClass
{
public int Value { get; set; }
}
public struct MyStruct
{
public int Value { get; set; }
}
public class Test
{
public bool ContainerReturnsNothing<T>(T input)
{
var container = new Container<T>();
var output = container.DoSomething(input);
return output.Equals(default(T));
}
public void TestAClassAndAStruct()
{
ContainerReturnsNothing(new MyClass() {Value = 1}); // true
ContainerReturnsNothing(new MyStruct() {Value = 1}); // true
}
}
default(MyStruct)
将始终将IsConstructed
设置为false
- 每个实例化的结构将始终将
IsConstructed
设置为true
这就避免了这个问题,因为它们永远不会相等。换言之:
var myStruct = new MyStruct(0);
var isNull = myStruct.Equals(default(MyStruct));
isNull
为false,因为myStruct
和default(myStruct)
为IsConstructed
包含不同的值(true
和false
)
如果您使用原始示例中的MyStruct
类运行相同的检查,isNull
将为真,因为所有属性都匹配,即MyStruct
和default(MyStruct)
都将属性值设置为0
,我看不到任何可能性(最多为c#8)这应该如何工作Nullable
(或int?
)仍然只是一种值类型而不是引用,并且没有通用约束规定“T
应该是class
或Nullable
”。因此,如果没有编译器支持,您可能会在value的构造函数中引发异常。您能描述一下什么是正确的null值处理吗?也许与默认值(T)
相比更适合您?我们尝试介绍3个选项:1:我知道值,2:值为空,3:我不知道值。我们的值容器包含一个bool NoValue和一个对类型值的引用。因为某些参与方给我们null,所以我们必须使用nullable。