小编Jes*_*rew的帖子

通过base/sibling类阻止受保护成员访问的真正原因是什么?

我最近发现派生类中的方法只能通过派生类(或其子类之一)的实例访问基类的受保护实例成员:

class Base
{
    protected virtual void Member() { }
}

class MyDerived : Base
{
    // error CS1540
    void Test(Base b) { b.Member(); }
    // error CS1540
    void Test(YourDerived yd) { yd.Member(); }

    // OK
    void Test(MyDerived md) { md.Member(); }
    // OK
    void Test(MySuperDerived msd) { msd.Member(); }
}

class MySuperDerived : MyDerived { }

class YourDerived : Base { }
Run Code Online (Sandbox Code Playgroud)

我设法通过向基类添加静态方法来解决此限制,因为允许Base的方法访问Base.Member,而MyDerived可以调用该静态方法.

不过,我仍然不明白这种限制的原因.我已经看到了几个不同的解释,但他们无法解释为什么仍然允许MyDerived.Test()访问MySuperDerived.Member.

Principled说明:'受保护'意味着它只能被该类及其子类访问.YourDerived 可以覆盖Member(),创建一个只能由YourDerived及其子类访问的新方法.MyDerived无法调用重写的yd.Member()因为它不是YourDerived的子类,并且它不能调用b.Member(),因为b实际上可能是YourDerived的一个实例.

好的,但是为什么MyDerived可以调用msd.Member()?MySuperDerived可以覆盖Member(),并且只有MySuperDerived及其子类才能访问该覆盖,对吧?

直到运行时才知道您是否正在调用被覆盖的成员.当成员是一个字段时,它无论如何都不能被覆盖,但仍然禁止访问.

实用主义解释:其他类可能会添加您的类不了解的不变量,您必须使用它们的公共接口,以便它们可以维护这些不变量.如果MyDerived可以直接访问YourDerived的受保护成员,它可能会破坏这些不变量.

我同样的反对意见适用于此.MyDerived不知道MySuperDerived可能添加的不变量 - 它可能由不同的作者在不同的程序集中定义 - 为什么MyDerived可以直接访问其受保护的成员?

我得到的印象是,这种编译时限制是作为一种错误的尝试来解决一个实际上只能在运行时解决的问题.但也许我错过了一些东西.有没有人有这将通过类型YourDerived或基地的变量让MyDerived访问基地的保护成员造成的,但问题的例子不是 …

c# protected

14
推荐指数
2
解决办法
3739
查看次数

为什么我需要一个中间转换从struct到decimal,而不是struct到int?

我有这样的结构,显式转换为float:

struct TwFix32
{
    public static explicit operator float(TwFix32 x) { ... }
}
Run Code Online (Sandbox Code Playgroud)

我可以使用一个显式转换将TwFix32转换为int: (int)fix32

但要将其转换为十进制,我必须使用两个强制转换: (decimal)(float)fix32

没有从float到int或decimal的隐式转换.为什么编译器让我在进入int时省略了浮动的中间转换,但是当我要去小数时呢?

c# operators

8
推荐指数
1
解决办法
371
查看次数

用于解决具有重叠卡的游戏的结构/算法

考虑一下沿着Tower Solitaire,Tripeaks或Fairway Solitaire线路的纸牌游戏:桌子上有一些可立即使用的牌,每张牌都可以覆盖下面的其他牌(阻止他们玩牌).你有一张"基础"牌,你可以从桌子上取出一张牌,如果它只是你的基础牌之上或之下的一个等级,那么它就成了你的新基础牌.当您无法从牌桌上打牌时,您可以使用有限数量的替换牌进行抽牌,因此您通常希望尽可能打出最长的牌.

首先,您如何代表董事会以便寻找解决方案?其次,你会用什么算法来找到最长的可玩序列?

例:

  -4a- -5-
-3-  -2- -4b-

底部卡片卡在顶部被移除:你不能删除4a,直到3和2都消失.假设您的起始牌是王牌,这里的最佳游戏将是2,3,4b,5,4a.(你可以玩2,3,4a,但那不太好.)

我想这应该表示为某种有向图.你有从3和2到4a以及从2到4b到5的边缘,但你是否还有3到2之间以及4a和5之间的边缘,因为一个可以在另一个之后播放?如果是这样,它们是否可以按任意顺序播放(3然后2,或2然后3)这样的事实会在图形中形成一个循环,阻止您使用有效的"最长路径"算法?(我相信如果图形包含循环,在图形中找到最长的路径是NP完全的.)

algorithm graph solver

7
推荐指数
1
解决办法
3733
查看次数

如何让CruiseControl.NET与Mercurial一起使用:"源控制失败(GetModifications)"

我正在尝试为自动构建设置CruiseControl.NET 1.5.7256.1.我的项目存储在Mercurial中,我使用以下内容ccnet.config:

<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
    <project name="Slider" webURL="http://localhost/ccnet">
        <triggers>
            <intervalTrigger seconds="3600" />
        </triggers>
        <sourcecontrol type="hg" autoGetSource="true">
            <executable>C:\Python26\Scripts\hg.bat</executable>
            <repo>c:\repos\slider</repo>
            <workingDirectory>c:\ccnet\slider</workingDirectory>
        </sourcecontrol>
        <tasks>
            <msbuild>
                <executable>C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe</executable>
                <workingDirectory>c:\ccnet\slider</workingDirectory>
                <projectFile>Slider.sln</projectFile>
                <buildArgs>/noconsolelogger /p:Configuration=Debug /v:diag</buildArgs>
                <targets>Slider</targets>
                <timeout>900</timeout>
                <logger>C:\Program Files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
            </msbuild>
        </tasks>
    </project>
</cruisecontrol>
Run Code Online (Sandbox Code Playgroud)

但是当我强制构建时,我收到此错误:

[Slider:WARN] Source control failure (GetModifications): Source control operation failed: < was unexpected at this time.
. Process command: C:\Python26\Scripts\hg.bat log -r 0:123 --template <modification><node>{node|short}</node><author>{author|user}</author><date>{date|rfc822date}</date><desc>{desc|escape}</desc><rev>{rev}</rev><email>{author|email|obfuscate}</email><files>{files}</files></modification> --noninteractive
[Slider:INFO] Integration complete: Exception - 12/2/2010 1:19:08 PM
Run Code Online (Sandbox Code Playgroud)

该错误可能是由--template参数中的未引用尖括号引起的,但是如何让CC.NET在该参数周围加上引号呢?

===============

这是hg.bat:

@echo off
rem …
Run Code Online (Sandbox Code Playgroud)

cruisecontrol.net mercurial continuous-integration

7
推荐指数
1
解决办法
2645
查看次数

Mercurial:如何将更改合并到另一个分支中重命名的文件?

我有一个Mercurial存储库,里面有四个分支.一个是"共同"分支,另外三个是"特定"分支,其由应用于公共分支的一些外观变化组成.其中一个外观变化包括重命名一些文件.

因此,公共分支具有"file.txt",并且第一个特定分支具有"file-01.txt",该文件相同的文件,用于相同的目的但具有不同的名称和略微不同的内容.它在特定分支上重命名为file-01.txt,"hg log -f file-01.txt"正确显示重命名之前的历史记录.

当我在公共分支上对file.txt进行更改时,我需要能够将该更改合并到特定分支上的file-01.txt中.但Mercurial不明白文件是一样的.它告诉我:

远程更改了本地删除的file.txt

使用(c)吊死版本或假期(d)分开?

如果我选择"c"然后我得到一个新的file.txt,其中包含公共分支版本中的确切内容.如果我选择"d",则根本不会合并更改.

我该怎么做才能做到这一点?


编辑:我可以使它在一个新的测试库中正常工作,但不是我的实际回购.这是我得到的(请注意,rev 118位于特定分支上,就在原始重命名之前,所以我将再次通过重命名过程来说明):

C:\ ...> hg update -C 118

更新了0个文件,合并了0个文件,删除了0个文件,未解析了0个文件

C:\ ...> hg合并默认值

合并file.txt
合并anotherfile.txt
0文件更新,2文件合并,0文件删除,0文件未解析
(分支合并,别忘了提交)

所以它没有重命名.但如果我重命名,它会失败:

C:\ ...> hg update -C 118

更新了2个文件,合并了0个文件,删除了0个文件,解析了0个文件

C:\ ...> hg重命名file.txt文件-01.txt
C:\ ...> hg commit -m"重命名"

创造了新的头脑

C:\ ...> hg合并默认值

远程更改了file.txt哪个本地删除
使用(c)挂起版本或者离开(d)eleted?


编辑2:这是我在最后一步得到的hg merge --debug default:

搜索副本返回rev 115
本地不匹配的文件:
file-01.txt
找到所有副本(*=合并,!=发散):
file-01.txt - > file.txt

检查目录重命名
解析清单
覆盖无部分虚假
祖先9d979018c2df本地f842fdbc252b +远程05fc75e480da
anotherfile.txt:版本不同 - > m
远程更改file.txt哪个本地删除
使用(c)挂起版本或离开(d)eleted?

merge mercurial rename

6
推荐指数
1
解决办法
5081
查看次数

在VS 2017自定义项目系统中,如何在解决方案资源管理器中将项目项设置为粗体?

我正在为VS 2017编写项目系统扩展,并且我的语言中的每个项目都有一个文件,即"启动文件".我希望该文件在解决方案资源管理器中显示为粗体.

用于VS的Python工具可以满足我的需求,但我的扩展是基于新的项目系统框架(CPS).更改解决方案资源管理器项目外观的CPS方法是实现IProjectTreePropertiesProvider,但我没有看到任何方式用它来更改文本样式 - 只有图标.

extensibility visual-studio vs-extensibility visual-studio-2017 common-project-system

5
推荐指数
1
解决办法
454
查看次数

"只有赋值,调用,递增,递减和新对象表达式才能用作语句"

我在我的ac#console应用程序代码中收到此错误

 case 5:
    Console.WriteLine("User selected to Quit, option " + response);
    Environment.Exit;
    break;
Run Code Online (Sandbox Code Playgroud)

//错误只有赋值,调用,递增,递减和新对象表达式才能用作语句

c# environment console quit

-2
推荐指数
1
解决办法
1万
查看次数