我试图围绕面向对象的编程.但我遇到了一些麻烦.我(想)我理解为什么OOP是一个'好'设计的一般概念和论据.当我坐下来尝试编写OOP代码时,我的问题出现了.
我倾向于最终得到程序,这些程序要么是非常程序性的,要么偶尔会把对象扔进去......或者程序对于他们正在做的事情看起来非常冗长和复杂......一切都是对象; 但是有许多很多物体和遗传树长得又长又丑.
我一直试图找到的是一些非常重要的例子(我已经看到很多涉及猫,狗和动物的扔掉/伪代码......但是当我真正尝试时它们似乎没有帮助设计真正精心设计的OOP源代码来编写需要做某些事情的东西.理想情况下,我正在寻找能够引导我完成思考过程的东西.就像'好吧 - 这里有一些做XYZ的程序代码.现在,这里有一些非常棒的OOP代码可以做同样的事情!'
谢谢
有一个问题比较C#代码和VB.NET,看似相同的代码之间的结果是完全不同的.(我编写了一个程序,允许两个类"战斗".无论出于何种原因,C#总能获胜.BB.NET有什么问题?)
给出的解释是C#将初始化类字段,然后调用基础构造函数,但VB.NET完全相反.
我的问题是 - 为什么?
这些语言有不同的技术原因吗?乍一看,似乎任何一种方法都同样有效,但我无法理解为什么他们不会选择相同的方法.
编辑:正如'Jeffrey L Whitledge'指出的那样,VB6没有继承,所以我认为我们不能说'保持VB.NET和VB6更紧密相关'.
寻找对此的澄清......
我听说.Net中的'一切'都是从Object继承而来的.我还听说过值类型和引用类型之间的区别在于引用类型从Object继承而值类型没有.
我的理解是一切都是一个对象(继承自System.Object); 但是价值类型和参考类型只是彼此"不同".值类型在堆栈上分配,引用类型获得放置在堆栈上的"指针",指向堆上的地址.
这是它的要点吗?什么使Integer成为值类型?这是语言固有的东西?
我确定我做错了什么; 但这已经让我疯狂一段时间了.
我做了一个小型的Silverlight游戏(旧的Galaxian克隆).当游戏开始~90%的时候,一堆星星随机定位在游戏区域.有三种类型的恒星 - 更大的恒星更快,更小的恒星运动更慢.
它看起来像这样:

大约10%的时间所有星星出现在'乐队'中

我认为值得一提的是,即使它们处于狭窄的范围内; 他们并非都处于同一个位置.所以它就像它仍然生成一个随机数 - 只是一个小数字.
要重现错误,我只需在浏览器中点击"f5"即可.几乎所有时间,它都按预期工作.很少,我得到乐队.再次点击'f5'将解决问题.
没有张贴巨大的代码墙; 我认为这是最相关的代码.它出现在Base类中,我的所有星星都继承自.当每个星星被创建时,它会被调用一次.
Protected Sub SetInitialPosition()
myElipse.Height = GetStarSize()
myElipse.Width = GetStarSize()
_location.X = GetRandom.Next(-1 * Settings.StarEdge, CType(GameCanvas.Width, Integer) + Settings.StarEdge)
_location.Y = GetRandom.Next(0, CType(GameCanvas.Height, Integer))
myElipse.Fill = New SolidColorBrush(GetStarColor)
End Sub
Run Code Online (Sandbox Code Playgroud)
我没有看到任何错误.GetRandom()返回一个单例Random类,我依赖于GameCanvas.Height和GameCanvas.Width是有效的 - 但同样,.Width似乎完全按预期工作.
有没有人对这种行为有可能的解释?生成随机数时是否有任何需要注意的问题?每次我单步执行代码,一切都很好,游戏按预期工作.
如果有帮助我可以发布游戏链接.
(http://robdude.weebly.com/cci.html)
编辑#1:
这是来自GetRandom()的代码
Protected Shared Function GetRandom() As Random
If _random Is Nothing Then _random = New Random()
Return _random
End Function
Run Code Online (Sandbox Code Playgroud)
编辑#2: 我非常感谢大家对此的想法/建议.
我以前从未想过它; 但我最近学会了如何修改app.config文件以添加/删除跟踪侦听器(例如,将所有Trace.WriteLine输出重定向到文本文件).
但我不太明白它是如何工作的?有人可以解释一下吗?
我知道相应的C#代码与配置相同(在本例中) - 该代码是否在我的应用程序入口点之前生成/执行?
这主要是学术性的 - 但我正在研究ValueTypes的Equals()实现.源代码在这里:http://referencesource.microsoft.com/#mscorlib/system/valuetype.cs#38
引起我注意的代码是这样的:
// if there are no GC references in this object we can avoid reflection
// and do a fast memcmp
if (CanCompareBits(this))
return FastEqualsCheck(thisObj, obj);
Run Code Online (Sandbox Code Playgroud)
FastEqualsCheck()声明如下:
[System.Security.SecuritySafeCritical]
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool FastEqualsCheck(Object a, Object b);
Run Code Online (Sandbox Code Playgroud)
我的理解是'[MethodImplAttribute(MethodImplOptions.InternalCall)]'表示这是在CLR中实现的(源不可用),但我想我可以直接从我的代码中调用它.当我尝试时,我得到一个SecurityException
ECall methods must be packaged into a system module.
我可以自己进行这些调用(或者它们仅用于内部消费)吗?如果我可以直接打电话给他们,这样做的适当方法是什么?
我主要是一个神谕新手,所以请原谅我,如果这是一个愚蠢的问题......
我有一个名为'CODE'的模式,其存储过程执行任意SQL(现在,请忽略与之相关的潜在安全问题).传入的SQL将选择数据; 但是所有数据都驻留在模式A,B或C中 - 但SQL只能一次从一个模式中选择.
例如:类型A的用户创建一个字符串'SELECT*FROM A.USERTABLE' - 而类型B的用户创建一个字符串'SELECT*FROM B.USERTABLE'.
我要做的是允许用户不明确指定他们的架构.在前端.net应用程序中; 我已经知道它们是A型,B型还是C型.我希望这三个只需输入'SELECT*FROM USERTABLE'.
我遇到的问题是我不知道该怎么做.我的应用程序只能在'CODE'模式中执行proc - 所以我不能只复制代码并让用户A调用'A.ExecuteSQL'.
我尝试过几件事; 但迄今为止没有任何工作.我希望ExecuteSQL proc保留在CODE模式中; 但是当'USERTABLE'传入时,我需要知道有时这意味着A.USERNAME,有时候是B.USERNAME.
有什么建议?
这不是学校作业或任何事情,但我意识到这是一个主要的学术问题.但是,我一直在努力做的是解析"数学"文本并提出答案.
例如 - 我可以弄清楚如何解析'5 + 5'或'3*5' - 但是当我尝试正确地将操作链接在一起时我失败了.
(5 + 5)*3
这大多只是让我烦恼,我无法弄明白.如果有人能指出我的方向,我真的很感激.
编辑 感谢您的所有快速回复.对不起,我没有更好地解释.
首先 - 我没有使用正则表达式.我也知道已有的库可以作为字符串使用数学表达式并返回正确的值.所以,我主要是看着这个,因为,遗憾的是,我并没有"明白".
第二 - 我尝试过的事情(可能是误入歧途),但我在计算'('和')'并首先评估最深的项目.在简单的例子中,这有效; 但我的代码不漂亮,更复杂的东西崩溃.当我'计算'最低级别时,我正在修改字符串.
所以...(5 + 5)*3
会变成10*3
然后评估为30
但它感觉"错了".
我希望这有助于澄清事情.我肯定会查看提供的链接.
如果这是一个愚蠢的问题,请原谅我,但我担心我不知道'堆栈'是什么.
我知道'堆栈'是什么,我已经学会了FILO/FIFO的首字母缩略词.但是当人们说'价值类型被分配在堆栈而不是堆上'时,我恐怕我真的不知道这意味着什么.
当我将一个逻辑错误引入递归函数时 - 我无法再为"堆栈"分配更多内存而我的应用程序崩溃了....但我真的不知道它是什么.
我试图谷歌寻求答案,但只找到关于'堆栈'的信息以及如何使用它.
当我运行.Net应用程序时 - 是否会创建一个"堆栈实例"来充当"堆栈"?我已经看到Stack跟踪向我展示了代码的执行级别 - 最常见的是当我遇到一个无法处理的异常时...但我记得能够看到的是方法和它们被调用的顺序......不会堆栈的每个步骤的范围内也包含所有变量.
也许我只是愚蠢 - 但我认为我可以想象一个具有递归函数的情况,它可以方便地查看变量的先前值 - 来自"堆栈"但不需要传递它.
Dunno,如果这有任何意义 - 这是非常晚.但我真的很感激任何人的信息.
这是我正在谈论的一个例子......
Public Class Sample1
Public Shared Function MyValue() As Integer
Return 0
End Function
Public Sub Code()
Dim ThisIsBad = Me.MyValue
Dim ThisIsGood = Sample1.MyValue
End Sub
End Class
Run Code Online (Sandbox Code Playgroud)
Me.MyValue在VB.NET中发出警告并且(等效代码给出)C#中的错误.这有什么特别的原因吗?我发现使用'Me.MyValue'访问共享函数更直观/自然 - 但我避免它将我的警告保持为0.
其他人只是决定'不,从另一个角度来做更有意义',还是有一些我不理解的技术原因?
编辑:
感谢大家.我认为它错了,更像是OOP中的"子类".即使在基类中声明了某些内容,也可以通过您拥有的实例访问它.但这种关系与共享或静态不同.