我已切换到在使用 C#8 的项目中启用可空。现在我有以下课程:
public class Request
{
public string Type { get; set; }
public string Username { get; set; }
public string Key { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
编译器当然抱怨它不能保证这些属性不会为空。除了添加接受不可为空字符串的构造函数之外,我看不到任何其他方法来确保这一点。
这对于一个小班级来说似乎很好,但是如果我有 20 个属性,这是在构造函数中列出所有属性的唯一方法吗?是否有可能以某种方式使用初始化程序强制执行它:
var request = new Request { Type = "Not null", Username = "Not null" }; // Get an error here that Key is null
Run Code Online (Sandbox Code Playgroud)
PS 有一个很好的答案,建议使用 iniatlizer 来处理属性,但这并不总是适用于例如Type不能只是初始化为某个随机值的类型
我有一个结构定义,其中包括以下字段:
pub struct Separated<'a, I, T>
{
..., // other fields,
separated: NonNull<dyn 'a + Iterator<Item = T>>,
}
Run Code Online (Sandbox Code Playgroud)
不久之后,在其构造函数中,我尝试将该字段初始化为悬空指针:
let sep = Separated {
..., // other fields
separated: NonNull::dangling(),
};
Run Code Online (Sandbox Code Playgroud)
奇怪的是,这会产生此错误:
error[E0282]: type annotations needed
|
16 | separated: NonNull::dangling(),
| ^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
Run Code Online (Sandbox Code Playgroud)
这个领域没有什么神秘之处。它的类型在结构定义中明确设置。我不明白为什么类型推断器不能推断出合适的类型来注入那里。
可以在下方和操场上找到产生此错误的最小 20 行示例:
use std::pin::Pin;
use std::ptr::NonNull;
pub struct Separated<'a, T> {
t: &'a T,
separated: NonNull<dyn 'a + Iterator<Item = T>>,
}
impl<'a, T> Separated<'a, …Run Code Online (Sandbox Code Playgroud) 我一直听到人们谈论非可空引用类型将如何解决如此多的错误并使编程变得更加容易.即使是null的创建者也称它为十亿美元的错误,而Spec#引入了非可空类型来解决这个问题.
编辑:忽略我对Spec#的评论.我误解了它是如何工作的.
编辑2:我必须和错误的人交谈,我真的希望有人能够与之争辩:-)
所以我猜想,在少数人中,我错了,但我不明白为什么这场辩论有任何优点.我认为null是一个bug查找工具.考虑以下:
class Class { ... }
void main() {
Class c = nullptr;
// ... ... ... code ...
for(int i = 0; i < c.count; ++i) { ... }
}
Run Code Online (Sandbox Code Playgroud)
BAM!访问冲突.有人忘了初始化c.
现在考虑一下:
class Class { ... }
void main() {
Class c = new Class(); // set to new Class() by default
// ... ... ... code ...
for(int i = 0; i < c.count; ++i) { ... …Run Code Online (Sandbox Code Playgroud) 只是好奇.
如果你走的话:
string myString;
Run Code Online (Sandbox Code Playgroud)
它的值为null.
但如果你去:
int myInt;
Run Code Online (Sandbox Code Playgroud)
C#中此变量的值是多少?
谢谢
大卫
我有一个属性:
public decimal? DejanskaKolicina { get; set; }
Run Code Online (Sandbox Code Playgroud)
和Resharper告诉我:
明确指定字符串转换中的文化
但如果我使用:
DejanskaKolicina.ToString(CultureInfo.CurrentCulture)
Run Code Online (Sandbox Code Playgroud)
我总是得到以下信息:
ToString方法有0个参数但是用1个参数调用它
如果我更改小数属性,使其不再可为空,那么它的工作原理.我如何使用ToString(CultureInfo.CurrentCulture)可空属性?
我从eclipse得到一个警告,我知道我可以通过抑制警告将其删除,但我更愿意理解是什么原因导致它可能为空.
package-info.java
@ParametersAreNonnullByDefault
package test;
import javax.annotation.ParametersAreNonnullByDefault;
Run Code Online (Sandbox Code Playgroud)
test.java
package test;
public class Test {
public static void main( final String[ ] args ) {
System.out.println( new Test( "a" ).getS( ) );
}
private final String s;
public Test( final String s ) {
this.s = s;
}
public String getS( ) {
return this.s;//Null type safety: The expression of type String needs unchecked conversion to conform to '@Nonnull String'
}
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么我得到这个警告......
PS:
public Test( @Nonnull final String s ) …
我有一个像这样的方法:
public void foo(@Nonnull String value) {...}
Run Code Online (Sandbox Code Playgroud)
我想编写一个单元测试,以确保foo()当抛出NPE value是null,但我不能,因为编译器拒绝当IDE启用静态空指针流分析编译单元测试.
如何使此测试编译(在Eclipse中启用"启用基于注释的空分析"):
@Test(expected = NullPointerException.class)
public void test() {
T inst = ...
inst.foo(null);
}
Run Code Online (Sandbox Code Playgroud)
注意:理论上,编译器的静态空指针应该阻止这样的情况.但是没有什么能阻止某人在关闭静态流分析的情况下编写另一个模块并调用该方法null.
常见情况:没有流量分析的大杂乱旧项目.我首先注释一些实用程序模块.在这种情况下,我只好现有或新的单元测试,其检查代码的行为对所有模块不使用流量分析还.
我的猜测是,我必须将这些测试移动到一个未经检查的模块中,并在我进行流量分析时移动它们.这将有效并且符合哲学,但这将是很多手工工作.
换句话说:我不能轻易编写一个测试,上面写着"当代码无法编译时成功"(我必须将代码片放入文件中,从单元测试中调用编译器,检查输出是否有错误. .. 不漂亮).那么如何在调用者忽略时轻松测试代码失败@Nonnull?
java unit-testing exception nullpointerexception non-nullable
我认为在新的 Dart 规则中,变量不能声明/初始化为 null。所以我们必须late在变量类型之前放置一个关键字,如下所示:
late String id;
Run Code Online (Sandbox Code Playgroud)
或者?变量类型后面的标记,如下所示:
String? id;
Run Code Online (Sandbox Code Playgroud)
这两者是相等的还是有一些区别?
当我写下这个声明时:
var x = new ClassName();
x隐式键入为ClassName?. 也就是说,由于ClassName是引用类型,因此隐式赋值会var自动定义为可空(即使我提供非空实例并且从不修改它)。
我的问题是,在使用“var”关键字时,有什么方法可以使非空性成为默认值吗?
我知道这个问题和相关信息:Why does Visual Studio Type a Newly Minted Array as Nullable?
只是尝试使用 C# 8.0 Beta 并更新一些代码以使用可为 null 的引用类型。
我有一个用于 Trie 实现的节点样式类。每个节点都有一个类型为 的值T。根节点的构造函数不需要值,因此我将其设置为default。
这是一个简短的版本:
public class Trie<T>
{
public readonly bool caseSensitive;
public readonly char? letter;
public readonly Dictionary<char, Trie<T>> children;
public readonly Trie<T>? parent;
public readonly int depth;
public bool completesString;
public T value;
public Trie(bool caseSensitive = false)
{
this.letter = null;
this.depth = 0;
this.parent = null;
this.children = new Dictionary<char, Trie<T>>();
this.completesString = false;
this.caseSensitive = caseSensitive;
this.value = default;
}
}
Run Code Online (Sandbox Code Playgroud)
如果 ctor …
non-nullable ×10
c# ×5
null ×3
java ×2
nullable ×2
annotations ×1
c#-10.0 ×1
c#-8.0 ×1
cultureinfo ×1
d ×1
exception ×1
flutter ×1
generics ×1
null-pointer ×1
pointers ×1
rust ×1
unit-testing ×1