所以,据我所知,这在C中是合法的:
foo.c的
struct foo {
int a;
};
Run Code Online (Sandbox Code Playgroud)
bar.c
struct foo {
char a;
};
Run Code Online (Sandbox Code Playgroud)
但功能相同是非法的:
foo.c的
int foo() {
return 1;
}
Run Code Online (Sandbox Code Playgroud)
bar.c
int foo() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
并将导致链接错误(函数的多重定义foo
).
这是为什么?结构名称和函数名称之间的区别是什么使C无法处理一个而不能处理另一个?这种行为也扩展到C++吗?
在 C# 9 中,我们可以创建位置记录,使它们获得一个构造函数,规范草案将其称为主构造函数。我们也可以创建自定义构造函数,但如规范中所述:
如果记录具有主构造函数,则任何用户定义的构造函数(“复制构造函数”除外)都必须具有显式的 this 构造函数初始值设定项。
所以这是不允许的:
public record A(string Foo, int Bar)
{
public A(MyClass x)
{
Foo = x.Name;
Bar = x.Number;
}
}
Run Code Online (Sandbox Code Playgroud)
并且确实导致 CS8862“在带有参数列表的记录中声明的构造函数必须具有 'this' 构造函数初始值设定项。” 我们必须写:
public record A(string Foo, int Bar)
{
public A(MyClass x) : this(x.Name, x.Number) {}
}
Run Code Online (Sandbox Code Playgroud)
反而。在这种情况下,这几乎不是问题,但可以想象一个更长的初始化逻辑,它不适合this
构造函数初始化程序。
问题是:为什么存在这种限制?我猜想解除它会以某种方式打破记录的某些功能,但这是一个足够新的功能,我无法想出办法来做到这一点。自动生成的主构造函数是否做了一些对记录正常工作至关重要的事情,因此必须调用它?
我有一个容器类型C<T>
,其中包含类型的对象T
。
struct C<T> {
insides: T
}
Run Code Online (Sandbox Code Playgroud)
假设我有两种类型A
,B
可以使用From
特征进行转换:
struct A { }
struct B { }
impl From<A> for B {
fn from(a: A) -> B {
B { }
}
}
Run Code Online (Sandbox Code Playgroud)
就我而言,很自然地,我应该能够使用此转换轻松地将其放置在需要的C<A>
地方C<B>
。From
这可以通过扩展到容器类型来完成:
impl From<C<A>> for C<B> {
fn from(ca: C<A>) -> C<B> {
C { insides: B::from(ca.insides) }
}
}
fn foo(cb: C<B>) {}
fn main() {
let ca = C { insides: …
Run Code Online (Sandbox Code Playgroud) 考虑带有委托的逆变接口定义:
public interface IInterface<in TInput>
{
delegate int Foo(int x);
void Bar(TInput input);
void Baz(TInput input, Foo foo);
}
Run Code Online (Sandbox Code Playgroud)
Baz
失败的定义出现错误:
CS1961
无效方差:类型参数“TInput
”必须在“IInterface<TInput>.Baz(TInput, IInterface<TInput>.Foo)
”上协变有效。'TInput
' 是逆变的。
我的问题是为什么?乍一看,这应该是有效的,因为Foo
委托与TInput
. 我不知道是编译器过于保守还是我遗漏了什么。
请注意,通常您不会在接口内声明委托,特别是这不会在早于 C# 8 的版本上编译,因为接口中的委托需要默认接口实现。
如果允许这个定义,有没有办法打破类型系统,或者编译器是否保守?
c# generics covariance contravariance default-interface-member
我正在尝试IConfigurationProvider
使用NSubstitute。我需要该方法bool TryGet(string key, out string value)
返回不同键的值。所以像这样:
var configProvider = Substitute.For<IConfigurationProvider>();
configProvider.TryGet("key1", out Arg.Any<string>()).Returns(x =>
{ x[1] = "42"; return true; });
Run Code Online (Sandbox Code Playgroud)
但这无法编译。我需要一个模拟方法来实际将out参数设置为适当的值,而不管该参数是什么-它是一个依赖项,被测单元使用自己的参数调用此方法,而我只是希望它“返回”(如通过填充out参数返回)正确的键值。
这应该为该问题提供更多视角:
var value = "";
var configProvider = Substitute.For<IConfigurationProvider>();
configProvider
.TryGet("key1", out value)
.Returns(x => {
x[1] = "42";
return true;
});
var otherValue = "other";
configProvider.TryGet("key1", out value);
configProvider.TryGet("key1", out otherValue);
Assert.AreEqual("42", value); // PASS.
Assert.AreEqual("42", otherValue); // FAIL.
Run Code Online (Sandbox Code Playgroud)
我需要两个断言都是正确的,因为该方法将由测试的类使用,并且可以自由传递它想要的任何out参数,我只需要用“ 42”填充即可。
$(document)
在 TypeScript 中使用会出现错误Supplied parameters do not match any signature of call target.
我正在使用 TypeScript 3.1、jQuery 3.3.1 和 @types/jQuery 3.3.29。
是 $(document)
弃用,我应该使用别的东西或者是它在类型定义文件的错误?
编辑:这个 TypeScript 文件的整个主体基本上是“Hello World!”。
$(document).ready(() => {
console.log("Hello World!");
});
Run Code Online (Sandbox Code Playgroud) 所以 EF Core 预览版 7 发布了,我决定将它与 C# 8 预览版和 .NET Core 3.0 预览版 7 一起使用。假设我有一个表示多对多关系的类:
public class A
{
public int Id { get; set; }
public ICollection<Relation> Relations { get; set; }
}
public class B
{
public int Id { get; set; }
public ICollection<Relation> Relations { get; set; }
}
public class Relation
{
public A A { get; set; }
public B B { get; set; }
public int AId { get; set; }
public int …
Run Code Online (Sandbox Code Playgroud) c# entity-framework-core .net-core c#-8.0 entity-framework-core-3.0
我将结构体的字段转换为指针*mut
,因此我将该结构体的引用声明为可变的。但后来我开始收到mut
不需要修饰符的警告。这对我来说似乎很奇怪,我显然正在改变一些东西,但又宣布它是mut
不必要的?这让我想到了这个最小的例子:
struct NonMut {
bytes: [u8; 5]
}
impl NonMut {
pub fn get_bytes(&self) -> &[u8] {
&self.bytes
}
}
fn potentially_mutate(ptr: *mut u8) {
unsafe { *ptr = 0 }
}
fn why(x: &NonMut) {
let ptr = x.get_bytes().as_ptr() as *mut u8;
potentially_mutate(ptr);
}
fn main() {
let x = NonMut { bytes: [1, 2, 3, 4, 5] };
println!("{}", x.get_bytes()[0]);
why(&x);
println!("{}", x.get_bytes()[0]);
}
Run Code Online (Sandbox Code Playgroud)
1
0
Run Code Online (Sandbox Code Playgroud)
显然,取消引用指针需要不安全的代码,但从某人刚刚编写自己的应用程序并决定调用why
(可能在外部板条箱中定义)的角度来看,这种行为似乎完全出乎意料。您在某处传递了一个明显不可变的引用,借用检查器将您的代码标记为正确,但在幕后有一个为该结构创建的可变引用。NonMut
这可能会导致在用户不知情的 …
c# ×4
.net-core ×2
generics ×2
rust ×2
.net ×1
c ×1
c#-8.0 ×1
c#-9.0 ×1
c++ ×1
covariance ×1
jquery ×1
linkage ×1
nsubstitute ×1
typescript ×1
unit-testing ×1