我有一个简单的程序,它根据用户提供的鼠标数据绘制几何图形.我有一个处理鼠标跟踪的类(它获取带有鼠标移动历史的List)和一个名为Shape的抽象类.从这个类中我可以得到一些额外的形状,比如Circle,Rectangle等 - 并且每个形状都会覆盖抽象的Draw()函数.
这一切都运行良好,但问题来自我希望用户能够手动切换所需的形状.我得到了鼠标数据,我知道应该绘制什么样的形状.问题是如何使代码"知道"它应该创建哪个对象并将适当的参数传递给构造函数.此时也不可能添加新的Shape衍生物,这是完全错误的.
我好像不想出来像这样的代码:
List<Shape> Shapes = new List<Shape>();
// somwhere later
if(CurrentShape == "polyline"){
Shapes.Add(new Polyline(Points));
}
else if (CurrentShape == "rectangle"){
Shapes.Add(new Rectangle(BeginPoint, EndPoint));
}
// and so on.
Run Code Online (Sandbox Code Playgroud)
上面的代码清楚地证明了开放封闭原则.问题是我没有任何好主意如何克服它.主要问题是不同的Shapes具有不同参数的构造函数,这使得它更加麻烦.
我很确定这是一个常见的问题,但我不知道如何克服它.你有什么想法吗?
前段时间,我一直在研究一个非常扭曲的项目 - 我只能在单个范围内编写代码,然后将其放入C#函数(由另一个模块).
我只能使用之前声明的名称空间(我对它们没有任何影响)并且只能使用我工作的作用域中的变量.因此,我无法更改标题和包含的库.
当我想操作泛型集合时出现问题 - 我既不能使用lambda表达式,也不能使用LINQ - 我根本无法放置using System.Linq;,因为我无法访问文件头.
我只需做一件简单的事情,没有LINQ或lambda就很容易管理.但是,之后我想知道会发生什么,如果我不得不在IEnumerable上使用一些更复杂的操作.从那以后,我的问题出现了:
是否可以在不更改文件头和添加新命名空间的情况下使用LINQ或lambdas?
让我们说我们有一个List<int> _Numbers = new List<int>();.让它充满一些数字.现在我想从中选择所有偶数.
与using System.Linq;在报头中,该溶液是显而易见的:
List<int> _NewList = _Numbers.Where(n => n % 2 == 0).ToList();
Run Code Online (Sandbox Code Playgroud)
要么
List<int> _NewList = (from _Number in _Numbers where _Number % 2 == 0 select _Number).ToList();
Run Code Online (Sandbox Code Playgroud)
但是如果不包含LINQ,我该如何实现呢?我的第一个猜测是这样的:
List<int> _NewList = System.Linq. // ??? What to add here?
Run Code Online (Sandbox Code Playgroud)
我知道这个问题很奇特,走这条路是很不寻常的,但我只是很好奇,而且我没有找到关于这个案例的信息.
我有一个带<appSettings>标签的配置文件.我希望它们中的一些是常量,并从另一个配置文件加载其中一些.
Web.config文件:
<appSettings>
<add key="commonKey1" value="commonValue1" />
<add key="commonKey2" value="commonValue2" />
<add key="commonKey3" value="commonValue3" />
<!-- ??? -->
</appSettings>
Run Code Online (Sandbox Code Playgroud)
AdditionalSettings.config
<appSettings>
<add key="AdditionalKey1" value="AdditionalValue1" />
<add key="AdditionalKey2" value="AdditionalValue2" />
</appSettings>
Run Code Online (Sandbox Code Playgroud)
结果:Web.config编译后应该像这样:
<appSettings>
<add key="commonKey1" value="commonValue1" />
<add key="commonKey2" value="commonValue2" />
<add key="commonKey3" value="commonValue3" />
<add key="AdditionalKey1" value="AdditionalValue1" />
<add key="AdditionalKey2" value="AdditionalValue2" />
</appSettings>
Run Code Online (Sandbox Code Playgroud)
如果所有值都存储在单独的文件中,这很容易:
<appSettings configSource="Settings.config" />
Run Code Online (Sandbox Code Playgroud)
但是我不知道如果基本文件中应该存在某些标签,如何合并两个文件,并且只应从单独的标签加载其他标签.
我也试过了
<appSettings configSource="Settings.config">
<add key="commonKey1" value="commonValue1" />
<add key="commonKey2" value="commonValue2" />
... etc
Run Code Online (Sandbox Code Playgroud)
但它不会起作用: A section using 'configSource' …
我正在研究.Net Native编译器执行的优化技术.我创建了一个示例循环:
for (int i = 0; i < 100; i++)
{
Function();
}
Run Code Online (Sandbox Code Playgroud)
我用Native编译了它.然后我.dll用IDA里面的机器代码反汇编了结果文件.结果,我有:
(我删除了一些不必要的行,所以不要担心地址行不一致)
我明白这add esi, 0FFFFFFFFh意味着subtract one from esi and alter Zero Flag if needed,所以如果还没有达到零,我们可以跳到开头.
我不明白的是为什么编译器重新循环?
我得出结论
LOOP:
add esi, 0FFFFFFFFh
jnz LOOP
Run Code Online (Sandbox Code Playgroud)
比例如更快
LOOP:
inc esi
cmp esi, 064h
jl LOOP
Run Code Online (Sandbox Code Playgroud)
但是真的是因为这个并且速度差异真的很重要吗?
我正在对CIL优化技术进行一些研究。我创建了以下简单代码:
int Function() { return 10; }
// (...)
int Number = Function();
Console.WriteLine(Number);
Run Code Online (Sandbox Code Playgroud)
当我在反汇编窗口中观看此代码时,会看到类似以下内容的内容:
00252DB0 mov ecx,0Ah
00252DB5 call 63A96648
00252DBA ret
Run Code Online (Sandbox Code Playgroud)
我知道它将10放入ecx,然后用作 函数63A96648指针WriteLine(),但是我不确定为什么要使用ecx寄存器。
我始终认为,ecx主要用于循环计数器(当然,这就是所谓的“计数寄存器”的一个原因......),我不知道为什么它用于WriteLine()功能,即使eax和ebx是免费的。即使编写更复杂的函数,最后也总是ecx在WriteLine()函数之前。
我试图在Internet上找到任何有关它的东西,甚至从我的大学图书馆里找到几本书,但什么都没找到。是ecx更快还是完全没有理由使用它?
我完全意识到我不应该对此太在乎(因为只要有效,我就可以了),但是过去几天一直在困扰我,我希望有人能告诉我为什么使用该寄存器。
我在Visual Studio 2015中遇到了一个奇怪的行为.我正在编写一个针对4.5.2 .Net Framework的应用程序:
然后在应用程序中,我尝试使用在C#6.0(来自.Net 6.0)中实现的一些东西:
int number = 456;
var name = nameof(number);
string str = $"Time = {DateTime.Now}";
Run Code Online (Sandbox Code Playgroud)
我很确定nameof使用的字符串格式$仅在.Net 4.6中可用,但我仍然可以编译此代码 - 尽管我的目标是4.5.2.
我在Visual Studio 2013中运行相同的代码,也针对4.5.2版本,但这次我无法编译代码(nameof未找到).
怎么可能,VS2015允许我编译目标.Net Framework版本中不应该允许的代码?
我在黑暗中拍摄的是VS2015能够将C#6.0代码计算到CIL中,这仍然与以前的版本兼容,但我不确定它是否是正确的猜测.
我正在使用javascript来嵌入嵌套在某些中的img元素<div>.之后我想将这些图像添加到字符串变量中.
我写道:
var SomeVariable="";
$("myDivId img").each(function(){
console.log(this);
SomeVariable += this;
});
console.log(SomeVariable);
Run Code Online (Sandbox Code Playgroud)
当console.log在使用.each功能,它显示是这样的:
<img (some elements)>,这正是我想要的.
当我最后使用console.log时,要写出整个价值,它说:
[object HTMLImageElement][object HTMLImageElement]
Run Code Online (Sandbox Code Playgroud)
我尝试使用一些转换,但我真的不知道如何实现它.
c# ×6
.net ×2
assembly ×2
.net-native ×1
asp.net-mvc ×1
c#-6.0 ×1
javascript ×1
lambda ×1
linq ×1
roslyn ×1
web-config ×1
x86 ×1