在类中声明一个类是有效的.(嵌套类)
在类中声明命名空间无效.
问题是:是否有任何好的理由(除了c ++语法/语法问题)禁止在类中声明命名空间?
至于我为什么要这样做,这里有一个例子:
让我们对二叉树容器进行基本的转换
template<typename Data>
class binary_tree
{
public:
... stuff ....
private:
... iterators class declaration ...
public:
typedef left_depth_iterator_impl left_depth_iterator;
typedef right_depth_iterator_impl right_depth_iterator;
typedef left_breadth_iterator_impl left_breadth_iterator;
typedef right_breadth_iterator_impl right_breadth_iterator;
... stuff ....
private:
Data data;
binary_tree* left;
binary_tree* right;
};
Run Code Online (Sandbox Code Playgroud)
现在我注意到我的类中有很多迭代器,所以我想在同一个命名空间中重新组合它们,如下所示:
template<typename Data>
class binary_tree
{
public:
... stuff ....
private:
... iterators class declaration ...
public:
namespace iterator
{
typedef left_depth_iterator_impl left_depth;
typedef right_depth_iterator_impl right_depth;
typedef left_breadth_iterator_impl left_breadth;
typedef right_breadth_iterator_impl right_breadth;
}
... stuff …Run Code Online (Sandbox Code Playgroud) 当我比较可空的短值时,编译器首先将它们转换为整数以与null进行比较.例如,考虑这个简单的代码:
short? cTestA;
if (cTestA == null) { ... }
Run Code Online (Sandbox Code Playgroud)
它由编译器转换为:
short? CS$0$0001 = cTestA;
int? CS$0$0002 = CS$0$0001.HasValue ? new int?(CS$0$0001.GetValueOrDefault()) : null;
if (!CS$0$0002.HasValue){ ... }
Run Code Online (Sandbox Code Playgroud)
这适用于包括.NET 4在内的所有.NET版本.
我在这里错过了什么?仅针对HasValue检查进行双重转换的原因是什么?
我期望编译器做的是使用.HasValue进行简单的检查if (cTestA.HasValue){}.至少这是我在发现此转换后在代码中执行的操作.
为什么所有这些额外的代码都添加了这么简单的测试?
有谁知道C#编译器编号文字修饰符的完整列表?
默认情况下,声明'0'使其成为Int32,'0.0'使其成为'Double'.我可以在末尾使用文字修饰符"f"来确保将某些内容视为"单个".比如这样......
var x = 0; // x is Int32
var y = 0f; // y is Single
Run Code Online (Sandbox Code Playgroud)
我可以使用的其他修饰符是什么?是否有一个强制Double,Decimal,UInt32?我试着谷歌搜索但找不到任何东西.也许我的术语是错误的,这就解释了为什么我的空白.任何帮助非常感谢.
以前我今天尝试添加两个ushorts,我注意到我必须将结果反馈给ushort.我认为它可能会成为一个uint(以防止可能的意外溢出?),但令我惊讶的是它是一个int(System.Int32).
是否有一些聪明的理由或者是因为int被视为'基本'整数类型?
例:
ushort a = 1;
ushort b = 2;
ushort c = a + b; // <- "Cannot implicitly convert type 'int' to 'ushort'. An explicit conversion exists (are you missing a cast?)"
uint d = a + b; // <- "Cannot implicitly convert type 'int' to 'uint'. An explicit conversion exists (are you missing a cast?)"
int e = a + b; // <- Works!
Run Code Online (Sandbox Code Playgroud)
编辑:就像GregS的回答所说,C#规范说两个操作数(在这个例子中是'a'和'b')应该转换为int.我对为什么这是规范的一部分的根本原因感兴趣:为什么C#规范不允许直接对ushort值进行操作?
我有一个A零和一个数组.我想找到所有数字的总和A.我想测试两个函数:
第一个功能
void test1(int curIndex){
if(curIndex == size) return;
test1(curIndex+1);
s+=A[curIndex];
}
Run Code Online (Sandbox Code Playgroud)
第二功能
void test2(int curIndex){
if(curIndex == size) return;
s+=A[curIndex];
test2(curIndex+1);
}
Run Code Online (Sandbox Code Playgroud)
我使用PAPI库来计算指令数量,这是整个实验:
#include <iostream>
#include <fstream>
#include "Statistics.h"
using namespace std;
int size;
int *A;
int s;
void test3(int curIndex){
if(curIndex == size) return;
test3(curIndex+1);
s+=A[curIndex];
}
int main(int argc, char* argv[]){
size = atoi(argv[1]);
if(argc!=2){
cout<<"type ./executable size{odd integer}"<<endl;
return 1;
}
if(size%2!=1){
cout<<"size must be an odd number"<<endl;
return 1; …Run Code Online (Sandbox Code Playgroud) 例如,
public int DoSomething(in SomeType something){
int local(){
return something.anInt;
}
return local();
}
Run Code Online (Sandbox Code Playgroud)
为什么编译器会发出无法在局部函数中使用 some 变量的错误?
public class PropertyManager
{
private Dictionary<ElementPropertyKey, string> _values = new Dictionary<ElementPropertyKey, string>();
private string[] _values2 = new string[1];
private List<string> _values3 = new List<string>();
public PropertyManager()
{
_values[new ElementPropertyKey(5, 10, "Property1")] = "Value1";
_values2[0] = "Value2";
_values3.Add("Value3");
}
public ref string GetPropertyValue(ElementPropertyKey key)
{
return ref _values[key]; //Does not compile. Error: An expression cannot be used in this context because it may not be returned by reference.
}
public ref string GetPropertyValue2(ElementPropertyKey key)
{
return ref _values2[0]; //Compiles
}
public …Run Code Online (Sandbox Code Playgroud) 以下代码提取无法编译导致not code paths return a value.这两种类型Test1StandardChargeCalculator,并Test2StandardChargeCalculator从返回类型的.
我知道如何解决这个问题,但我的问题是我为什么要这样做?A bool是值类型 - 因此只能表示true或false,这两个都在此代码段中得到满足.那么编译失败的原因呢?
internal StandardChargeCalculator Create()
{
bool value = true;
switch (value)
{
case true:
return new Test1StandardChargeCalculator();
case false:
return new Test2StandardChargeCalculator();
}
} //not all code paths return a value
Run Code Online (Sandbox Code Playgroud) C#语言(以及我确定的其他语言)在数字文字的末尾需要后缀.这些后缀表示文字的类型.例如,5m是小数,5f是浮点数.
我的问题是:这些后缀真的是必要的,还是可以从其上下文推断出文字的类型?
例如,代码decimal d = 5.0应该推断出它5.0不是double,而是小数.这种语法会导致问题吗?
我似乎遇到了C#编译器的一些奇怪行为.
请考虑以下代码示例:
static void Main(string[] args)
{
Foo(false, 8);
}
public static void Foo(bool execute, int x)
{
if (execute)
{
Task.Run(() => Console.WriteLine(x));
}
}
Run Code Online (Sandbox Code Playgroud)
运行此(在发布中)显示发生了一些意外的分配.检查IL表明闭包触发的堆分配出现在函数的最开头,而不是在条件内:
.method public hidebysig static void
Foo(
bool execute,
int32 x
) cil managed
{
.maxstack 2
.locals init (
[0] class Test.Program/'<>c__DisplayClass1_0' 'CS$<>8__locals0'
)
IL_0000: newobj instance void Test.Program/'<>c__DisplayClass1_0'::.ctor()
IL_0005: stloc.0 // 'CS$<>8__locals0'
IL_0006: ldloc.0 // 'CS$<>8__locals0'
IL_0007: ldarg.1 // x
IL_0008: stfld int32 Test.Program/'<>c__DisplayClass1_0'::x
// [18 13 - 18 25]
IL_000d: ldarg.0 …Run Code Online (Sandbox Code Playgroud) dynamicC#中的关键字可以让我这样做:
dynamic obj = ....;
var foo = obj.foo;
Run Code Online (Sandbox Code Playgroud)
obj.foo在运行时解析属性引用的位置.
由于属性是在运行时解析的,为什么不能将属性本身指定为变量?例如,
var propName = "foo";
var foo = obj[propName];
Run Code Online (Sandbox Code Playgroud)
?
我知道你可以通过反射或将对象转换为Dictionary来完成类似的事情.我对解决方案不感兴趣,因为它解释了为什么C#首先不支持类似Javascript的方括号查找.
我刚试图实现一个不可变的接口属性后发现,C#显然不支持我正在寻找的行为.我计划的很简单,对象会订阅一个包含不可变泛型属性的接口,这意味着没有setter的属性.但是,令我惊讶的是,订阅类仍然可以添加setter而不会出现任何错误.事实上,似乎C#接口完全忽略了属性的签名.它所关心的只是属性类型和名称.
例如:
namespace Some.Arbitrary.Framework
{
public interface IIdentifiable<T>
{
/// <summary>
/// Classes that subscribe to this interface
/// may still add a 'set;' signature.
/// </summary>
T Identifier { get; } // the lack of 'set;' is ignored
}
}
Run Code Online (Sandbox Code Playgroud)
我在StackOverflow上看到很多帖子说C#不支持这种行为,但我的问题是:为什么C#不支持我所描述的接口中的不可变属性?我打算做什么背后的基本设计缺陷?
c# ×9
.net ×2
c#-7.0 ×2
c++ ×2
ref ×2
class ×1
closures ×1
interface ×1
namespaces ×1
nullable ×1
performance ×1
roslyn ×1
types ×1
value-type ×1