我遇到了与多态类型(甚至多态接口)交互的接口概念的问题.我正在开发C#并希望接近这个定义的答案,尽管我认为这仍然为每个人提供了足够的空间来提出答案.
举个例子,假设你想制作一个绘制东西的程序.您可以为Paints定义一个接口,并为绘制的主体定义一个接口.此外,您还可以使用更具体的方式绘制一些主题.
interface IPainter {
void paint(IPaintable paintable);
}
interface IPaintable {
void ApplyBaseLayer(Color c);
}
interface IDecalPaintable : IPaintable {
void ApplyDecal(HatchBrush b);
}
Run Code Online (Sandbox Code Playgroud)
我可以想象制作一个类似于以下的画家:
class AwesomeDecalPainter : IPainter
{
public void paint(IPaintable paintable) {
IDecalPaintable decalPaintable = (IDecalPaintable)paintable;
decalPaintable.ApplyBaseLayer(Color.Red);
decalPaintable.ApplyDecal(new HatchBrush(HatchStyle.Plaid, Color.Green));
}
}
Run Code Online (Sandbox Code Playgroud)
当然,如果paintable没有实现IDecalPaintable,这将抛出.它立即引入了IPainter实现与其操作的IPaintable之间的耦合.但是我也认为说AwesomeDecalPainter不是IPainter是不合理的,因为它的使用仅限于IPaintable域的一个子集.
所以我的问题实际上是四方面的:
我有一个使用返回值处理错误的组件,而不是标准的异常处理.除了错误代码之外,它还返回错误发生位置的堆栈跟踪.我用来调用组件的包装器将解释返回代码并抛出异常.
我想让包装器抛出一个异常,其中包含从组件中捕获的堆栈跟踪信息.我希望它看起来好像异常是从错误的原始站点抛出的,即使它被抛到其他地方.更具体地说,id类似于visual studio测试运行器显示的堆栈跟踪,以反映正确的位置
有没有办法做到这一点?如果我可以避免访问私人成员的低级反射技巧,那也很好,但我会采取我能得到的.
编辑1: 我不关心如何捕获堆栈跟踪,我关心的是将已经捕获的堆栈跟踪附加到异常
编辑2:
我尝试重写StackTrace属性,但是visual studio正在从其他地方提取堆栈跟踪数据,并且似乎完全忽略了被覆盖的属性
CustomException GenerateExcpetion()
{
return new CustomException();
}
void ThrowException(Exception ex)
{
Trace.WriteLine("Displaying Exception");
Trace.WriteLine(ex.ToString());
var edi = ExceptionDispatchInfo.Capture(ex);
edi.Throw();
}
[TestMethod]
public void Test006()
{
var ex = GenerateExcpetion();
ThrowException(ex);
}
public class CustomException : Exception
{
string _stackTrace;
public CustomException()
{
_stackTrace = Environment.StackTrace;
}
public override string StackTrace
{
get
{
return base.StackTrace;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Excpetion.ToString()方法从私有属性中提取堆栈跟踪数据,因此来自覆盖的堆栈跟踪不会显示.
CustomException:抛出了类型'CustomException'的异常.
ExceptionDispatchInfo也从私有属性中查找堆栈跟踪数据,因此它无法找到任何该数据,并且当您抛出此自定义异常时,新的堆栈跟踪将附加到该异常,其位置为抛出.如果直接使用throw,则私有堆栈信息将设置为发生抛出的位置.
内容提供程序/解析程序API提供了一种使用URI openInputStream()和openOutputStream()方法在进程之间传输数据的复杂但强大的方法.自定义内容提供商能够openFile()使用自定义代码覆盖该方法,以有效地将URI解析为Stream; 但是,方法签名openFile()具有ParcelFileDescriptor返回类型,并且不清楚如何为此方法返回动态生成的内容生成正确的表示.
是否有ContentProvider.openFile()现有代码库中动态内容实现方法的示例?如果没有,你可以建议这样做的源代码或过程吗?
我很好奇什么情况确实需要使用jquery的$(document).ready()或prototype的dom:loaded或此事件的处理程序的任何其他变体.
在我测试的所有浏览器中,在结束标记之后立即开始与html元素和DOM进行交互是完全可以接受的.(例如
<div id="myID">
My Div
</div>
<script type="text/javascript">
$('#myID').initializeElement();
</script>
Run Code Online (Sandbox Code Playgroud)
所以在这一点上我想知道是否$(document).ready()只是为了减少编写在页面加载期间运行的javascript代码所涉及的思路.在使用的情况下,$(document).ready()在浏览器首先开始绘制页面和当页面"准备好"时实际执行的javascript之间存在定期渲染问题,例如弹出和"工件".
是否有$(document).ready()必要的场景?
是否有任何理由我不应该编写初始化脚本?
我使用ListBox在数据库中显示表的内容.每个列表框项都填充了Text属性设置为友好名称,Value属性设置为唯一ID列.数据库结构可能类似于以下内容:
CREATE TABLE GENERIC { FRIENDLY_NAME TEXT, ID INT }
Run Code Online (Sandbox Code Playgroud)
我尝试使用LINQ将列表框的项目转换为int []差不多一个小时,最终失败了.区分所选项目和未选择项目也很重要.这是我最后写的:
System.Collections.Generic.LinkedList<int>
selected = new LinkedList<int>(),
notSelected = new LinkedList<int>();
foreach (ListItem item in PhotoGalleryEdit_PhotoShoots.Items)
{
if (item.Selected)
selected.AddFirst(Convert.ToInt32(item.Value));
else
notSelected.AddFirst(Convert.ToInt32(item.Value));
}
int []arraySelected = selected.ToArray();
int []arrayNotSelected = notSelected.ToArray();
Run Code Online (Sandbox Code Playgroud)
任何人都可以在LINQ中展示如何做到这一点?
(我在C#中编写了所有代码,但用VB编写的任何答案都非常受欢迎)
c# ×3
.net ×2
android ×1
asp.net ×1
asp.net-3.5 ×1
file-io ×1
interface ×1
javascript ×1
jquery ×1
linq ×1
listbox ×1
oop ×1
polymorphism ×1