为什么我们需要在C#中装箱和拆箱?
我知道拳击和拆箱是什么,但我无法理解它的实际用途.我应该在哪里以及在哪里使用它?
short s = 25;
object objshort = s; //Boxing
short anothershort = (short)objshort; //Unboxing
Run Code Online (Sandbox Code Playgroud) Dave Herman最近在Rust 的演讲中说他们从C++借用了这个属性.我无法找到有关该主题的任何内容.有人可以解释一下单态意味着什么吗?
我在.ΝΕΤ上读过一些关于泛型的信息,并注意到一件有趣的事情.
例如,如果我有一个泛型类:
class Foo<T>
{
public static int Counter;
}
Console.WriteLine(++Foo<int>.Counter); //1
Console.WriteLine(++Foo<string>.Counter); //1
Run Code Online (Sandbox Code Playgroud)
两类Foo<int>,并Foo<string>在运行时不同.但是具有泛型方法的非泛型类呢?
class Foo
{
public void Bar<T>()
{
}
}
Run Code Online (Sandbox Code Playgroud)
很明显,只有一个Foo班级.但是方法Bar怎么样?所有泛型类和方法都在运行时使用它们使用的参数关闭.这是否意味着类Foo有许多实现,Bar并且有关此方法的信息存储在内存中?
我一直在和朋友聊天,有些人完全同意应该使用C++中的模板,其他人完全不同意.
一些好事是:
关于C++模板,您能告诉我哪些其他好处?
你能告诉我有关C++模板的哪些不好的事情?
编辑:我问这个的原因之一是我正在攻读考试,目前我正在讨论C++模板的主题.所以我想更多地了解它们.
我正在研究.net反思,我很难搞清楚差异.
据我所知,List<T>是一种通用的类型定义.这是否意味着.net反射T是泛型类型?
具体来说,我想我正在寻找有关Type.IsGenericType和Type.IsGenericTypeDefinition函数的更多背景知识.
谢谢!
我曾经认为C#中的Generics是这样实现的,当使用新的泛型类型时,在运行时或编译时生成一个新的类/方法/你有什么,类似于C++模板(我从来没有真正调查,我很可能是错的,我很乐意接受纠正.
但在我的编码中,我提出了一个确切的反例:
static class Program {
static void Main()
{
Test testVar = new Test();
GenericTest<Test> genericTest = new GenericTest<Test>();
int gen = genericTest.Get(testVar);
RegularTest regTest = new RegularTest();
int reg = regTest.Get(testVar);
if (gen == ((object)testVar).GetHashCode())
{
Console.WriteLine("Got Object's hashcode from GenericTest!");
}
if (reg == testVar.GetHashCode())
{
Console.WriteLine("Got Test's hashcode from RegularTest!");
}
}
class Test
{
public new int GetHashCode()
{
return 0;
}
}
class GenericTest<T>
{
public int Get(T obj)
{
return obj.GetHashCode();
}
} …Run Code Online (Sandbox Code Playgroud) Mono文档有一个关于完整AOT不支持通用接口实例化的代码示例:
interface IFoo<T> {
...
void SomeMethod();
}
Run Code Online (Sandbox Code Playgroud)
它说:
由于Mono无法从静态分析中确定哪种方法将实现接口,
IFoo<int>.SomeMethod因此不支持此特定模式."
所以我认为编译器无法在类型推断下使用此方法.但我仍然无法理解完全AOT限制的根本原因.
Unity AOT脚本限制仍存在类似问题.在以下代码中:
using UnityEngine;
using System;
public class AOTProblemExample : MonoBehaviour, IReceiver
{
public enum AnyEnum {
Zero,
One,
}
void Start() {
// Subtle trigger: The type of manager *must* be
// IManager, not Manager, to trigger the AOT problem.
IManager manager = new Manager();
manager.SendMessage(this, AnyEnum.Zero);
}
public void OnMessage<T>(T value) {
Debug.LogFormat("Message value: {0}", value);
}
}
public class Manager : …Run Code Online (Sandbox Code Playgroud) 问题“什么是具体化?” 对C#的泛型有评论:
通过使用反射检查类型实参,可以维护类型信息,从而可以在某种程度上进行专业化。但是,由于通用类型定义是在任何类型化发生之前就进行编译的事实,因此专业化的程度受到了限制(这是通过针对类型参数的约束对定义进行编译来完成的,因此,编译器必须能够即使没有特定的类型参数,也可以“理解”定义。
“专业化”是什么意思?它与带有特定类型参数的泛型类型的实例化不同吗?
“专业化程度受到限制”是什么意思?
为什么是“由于在没有任何验证发生之前就编译了通用类型定义的事实”的结果?
是否存在Task.WaitAll类似Task.WhenAll但不平行的无阻塞?
我写了这个,但也许是内置的?
public async Task<IEnumerable<T>> AwaitAllAsync<T>(IEnumerable<Task<T>> tasks)
{
List<T> result = new List<T>();
foreach(var task in tasks)
{
result.Add(await task);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
编辑:对于投票结束的人,我想知道是否存在等待所有任务以异步但顺序方式完成的构建方式.
@Anders:然后你正在做别的事情.告诉我们你的代码
考虑这段代码
public class SaveFooCommandHandler : ICommandHandler<SaveFooCommand>
{
private readonly IBusinessContext context;
public SaveFooCommandHandler(IBusinessContext context)
{
this.context = context;
}
public async Task Handle(SaveFooCommand command)
{
var foos = (await Task.WhenAll(command.Foos.Select(foo => context.FindAsync<Foo>(foo.Id))).ToList()
...
}
}
Run Code Online (Sandbox Code Playgroud)
那会失败,但是
var foos = await context.AwaitAllAsync(command.Foos.Select(foo => context.FindAsync<Foo>(foo.Id));
Run Code Online (Sandbox Code Playgroud)
不会,context.FindAsync是一个抽象dbcontext.Set<T>().FindAsync
你可以这么做await context.Set<Foo>().Where(f …
c# ×6
generics ×5
.net ×3
c++ ×2
async-await ×1
boxing ×1
jit ×1
mono ×1
overriding ×1
polymorphism ×1
reflection ×1
rust ×1
templates ×1