有没有办法在c#中将变量声明为Nullable?
struct MyStruct {
int _yer, _ner;
public MyStruct() {
_yer = Nullable<int>; //This does not work.
_ner = 0;
}
}
Run Code Online (Sandbox Code Playgroud) 我正在开发一个C#项目,我在其中声明了两个类变量:
DateTime creationDate;
byte exRecNo;
Run Code Online (Sandbox Code Playgroud)
该程序有一个while循环,其中这些变量分配了它们的值.我希望在每次迭代循环后将它们的值重置为null,以便不保留前一次循环中的值.
但是,当我尝试这样做时,我收到以下错误消息:
creationDate = null;
Run Code Online (Sandbox Code Playgroud)
"无法将null转换为'System.DateTime',因为它是一个不可为空的值类型"
exRecNo = null;
Run Code Online (Sandbox Code Playgroud)
"无法将null转换为'byte',因为它是一个不可为空的值类型"
由于我无法将它们设置为null,有什么方法可以清除它们的值?
我有这个功能:
public static U? IfNotNull<T, U>(this T? self, Func<T, U?> func)
where T : struct
where U : struct
{
return (self.HasValue) ? func(self.Value) : null;
}
Run Code Online (Sandbox Code Playgroud)
例:
int? maybe = 42;
maybe.IfNotNull(n=>2*n); // 84
maybe = null;
maybe.IfNotNull(n=>2*n); // null
Run Code Online (Sandbox Code Playgroud)
我希望它可以处理隐式可空引用类型以及显式Nullable<>类型.这种实现可行:
public static U IfNotNull<T, U>(this T? self, Func<T, U> func)
where T : struct
where U : class
{
return (self.HasValue) ? func(self.Value) : null;
}
Run Code Online (Sandbox Code Playgroud)
但是,当然重载分辨率不会考虑类型约束,因此您不能同时使用两者.这个问题有方法解决吗?
当我运行我的代码时,它告诉我adr的对象是null,这是真的,但是当它在同一个方法的副本中工作时,为什么它不会工作,使用insert而不是select的例外.
代码如下所示:
public City doesExist(string postnr, string navn, City city, SqlConnection con)
{
DatabaseConnection.openConnection(con);
using (var command = new SqlCommand("select Id from [By] where Postnummer='" + postnr + "' and Navn='" + navn + "'", con))
{
command.Connection = con;
SqlDataReader reader = command.ExecuteReader();
if (reader.Read())
{
city.id = reader.GetInt32(0);
city.postnr = postnr;
city.navn = navn;
reader.Close();
return city;
}
reader.Close();
return null;
}
}
public City create(string postnr, string navn, City city, SqlConnection con)
{
DatabaseConnection.openConnection(con);
using (var command …Run Code Online (Sandbox Code Playgroud) 查看以下代码块:
//Declaring nullable variables.
//Valid for int, char, long...
Nullable<int> _intVar;
Nullable<char> _charVar;
//trying to declare nullable string/object variables
//gives compile time error.
Nullable<string> _stringVar;
Nullable<object> _objVar;
Run Code Online (Sandbox Code Playgroud)
编译代码编译器时会出现以下错误消息:
类型'string'/'object'必须是非可空值类型,以便在泛型类型或方法'System.Nullable'中将其用作参数'T'
我读过好几次但仍然无法理解.任何人都可以澄清这个吗?为什么object或string不支持可空引用类型?
这是一个非常简单的问题 - 将类型 long 变量转换为 Nullable int 类型(int?)。(见下面的例子 - 不是实际的代码)
int? y = 100;
long x = long.MaxValue;
y = x;
Run Code Online (Sandbox Code Playgroud)
我收到编译时错误。
“无法将类型‘long’隐式转换为‘int?’。存在显式转换(您是否缺少强制转换?)。
我确实有解决方案(请参阅下面的解决方案部分),我对发布问题的好奇心是推荐的 3 种解决方案?
解决方案
y = Convert.ToInt32(x);
y = (int)x;
y = unchecked((int) x);
Run Code Online (Sandbox Code Playgroud)
预先感谢您的建议
如果我运行以下代码:
(int)Convert.ChangeType("3", typeof(int))
结果是3.真棒.
如果我将其更改为:
(int?)Convert.ChangeType("3", typeof(int?))
结果是
从'System.String'到'System.Nullable`1 [[System.Int32,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]'的无效演员表.
但是,它处理这个很好:
(int?)Convert.ChangeType("3", typeof(int))
为什么它不能直接处理转换为可空的int类型?
我有一个可以为空的字节,我想增加或设置为0取决于它是否为null,如下所示:
if (TheNullableByte == null)
{
TheNullableByte = 0;
}
else
{
TheNullableByte = TheNullableByte++;
}
Run Code Online (Sandbox Code Playgroud)
在javascript中我会这样写:
TheNullableByte = (TheNullableByte) ? TheNullableByte++ : 0;
Run Code Online (Sandbox Code Playgroud)
C#中有类似的东西吗?
我有一个扩展方法:
public static int DoStuff(this MyEnum? enumValue)
{
...
}
Run Code Online (Sandbox Code Playgroud)
我想在一个MyEnum已知不为null 的值上调用它:
MyEnum enumVal = ...
var x = enumVal.DoStuff(); // compiler error!
Run Code Online (Sandbox Code Playgroud)
错误:
错误CS1928:'MyEnum'不包含'DoStuff'的定义,最好的扩展方法重载'MyExtensions.DoStuff(MyEnum?)'有一些无效的参数
我可以通过声明扩展的重载来解决它:
public static int DoStuff(this MyEnum enumValue)
{
return DoStuff((MyEnum?)enumValue);
}
Run Code Online (Sandbox Code Playgroud)
或者,我可以显式调用扩展类:
var x = MyExtensions.DoStuff(enumVal);
Run Code Online (Sandbox Code Playgroud)
但这不直观.为什么不能Nullable<T>接受一个类型的扩展T,就像任何正常的方法签名一样?
我看到这样的代码,我理解为使数组可以为空但我不明白为什么我们需要它,因为数组是ref类型,所以它们已经可以为空了.
所以,我的问题是为什么我们需要这个呢?
private readonly decimal?[] _amounts = new decimal?[_count];
Run Code Online (Sandbox Code Playgroud)