更新:为了所有阅读本文的人的利益,自.NET 4起,由于自动生成事件同步的变化,锁定是不必要的,所以我现在就使用它:
public static void Raise<T>(this EventHandler<T> handler, object sender, T e) where T : EventArgs
{
if (handler != null)
{
handler(sender, e);
}
}
Run Code Online (Sandbox Code Playgroud)
并提出它:
SomeEvent.Raise(this, new FooEventArgs());
Run Code Online (Sandbox Code Playgroud)
在阅读过Jon Skeet 关于多线程的文章之后,我试图将他提倡的方法封装在像这样的扩展方法中引发事件(使用类似的通用版本):
public static void Raise(this EventHandler handler, object @lock, object sender, EventArgs e)
{
EventHandler handlerCopy;
lock (@lock)
{
handlerCopy = handler;
}
if (handlerCopy != null)
{
handlerCopy(sender, e);
}
}
Run Code Online (Sandbox Code Playgroud)
然后可以这样调用:
protected virtual void OnSomeEvent(EventArgs e)
{
this.someEvent.Raise(this.eventLock, this, e);
}
Run Code Online (Sandbox Code Playgroud)
这样做有什么问题吗? …
我经常对我必须包含在我的代码中的日志记录数量感到沮丧,这让我想知道是否有更好的做事方式.
我不知道这是否已经完成或是否有人提出了更好的想法,但我想知道是否有人知道将"记录器""注入"应用程序,以便被动地监视线程并安静地记录日志流程发生时不必执行以下操作:
public void MyProcess(int a, string b, object c)
{
log(
String.Format(
"Entering process MyProcess with arguments: [a] = [{0}]; [b] = [{1}]; [c] = [{2}]",
a.ToString(),
b,
c.ToString()
);
try
{
int d = DoStuff(a)
log(
String.Format(
"DoStuff({0}) returned value {1}",
a.ToString(),
d.ToString()
)
);
}
catch (Exception ex)
{
log(
String.Format("An exception occurred during process DoStuff({0})\nException:\n{1}",
a.ToString(),
ex.ToString())
)
}
}
Run Code Online (Sandbox Code Playgroud)
如果我可以对我的记录器说:
Monitor(MyClass.MyMethod)
Run Code Online (Sandbox Code Playgroud)
然后它将监视该方法内部的所有内容,包括传入参数以及方法调用和传递给这些方法的值,发生的异常等.
过去有没有人实现这样的东西?甚至可以实施吗?以这种方式登录只是一个梦想?
我喜欢设计能做到这一点的东西,但我甚至不知道我会从哪里开始.当然,我也不想重新发明轮子,如果它已经完成了,如果有人能指出我正确的方向,那就太好了.
任何建议都会感激不尽......
编辑:我想我会回答一个问题,询问日志中所需的详细程度.通常需要提供可配置级别的日志记录,以便如果配置指定详细日志记录,则记录所有内容,而如果配置了关键日志记录,则仅记录某些信息以及异常.如果配置了致命日志记录,则仅记录导致应用程序死亡的信息.这样的东西是可配置的还是AOP需要3或4个不同的构建,具体取决于日志记录级别的数量?
我经常使用4个级别:致命,严重,信息,详细
我们使用.NET 2.0框架和C#3.0(我认为它是C#的最后一个版本,它可以在2.0版本的框架上运行,如果我错了,请纠正我).
是否有内置于C#中的内容可以使这种类型的参数验证更方便?
public ConnectionSettings(string url, string username, string password,
bool checkPermissions)
{
if (username == null) {
throw new ArgumentNullException("username");
}
if (password == null) {
throw new ArgumentNullException("password");
}
if (String.IsNullOrEmpty(url)) {
throw new ArgumentException("Must not be null or empty, it was " +
(url == null ? url : "empty"), "url");
}
this.url = url;
this.username = username;
this.password = password;
this.checkPermissions = checkPermissions;
}
Run Code Online (Sandbox Code Playgroud)
这种参数验证成为一种常见的模式,并导致许多"近似样板"代码在我们的公共方法中跋涉.
如果没有内置的东西.我们可以使用哪些优秀的免费图书馆?
让我们创建一个您最喜欢的扩展方法列表.要获得资格,它应该是您经常使用的扩展方法,并且通过优雅,聪明,强大或非常酷而使编码更容易.
我将从我最喜欢的3种扩展方法开始,我发现它们优雅并且一直使用(我省略了代码检查参数是否有效以保持简短):
public static string FormatWith(this string text, params object[] values) {
return String.Format(text, values);
}
Run Code Online (Sandbox Code Playgroud)
所以不必写
String.Format("Some text with placeholders: {0}, {1}", "Item 1", "Item 2");
Run Code Online (Sandbox Code Playgroud)
你可以写
"Some text with placeholders: {0}, {1}".FormatWith("Item 1", "Item 2");
Run Code Online (Sandbox Code Playgroud)
public static T To<T>(this object obj) {
return (T) obj;
}
Run Code Online (Sandbox Code Playgroud)
所以不必写
object o = 5; //integer as object
string value = ((int)o).ToString(); //get integer value as string
int number = (int) o;
Run Code Online (Sandbox Code Playgroud)
你可以写
object o = 5; //integer …Run Code Online (Sandbox Code Playgroud) 我想使用列名作为参数,基于列列表生成多个SQL语句.
编辑:C#
var columns = new string[] { "COL1", "COL2" };
var tableName = "TABLE_1";
var prefix = "@"; // TODO get this from the provider factory
string sqlInsert = string.Format(
"INSERT INTO {0}\n( {1}) VALUES\n({2})",
tableName,
string.Join(", ", columns),
string.Join(", ", columns.Select(c => prefix + c)));
Run Code Online (Sandbox Code Playgroud)
生成的SQL:
INSERT INTO TABLE_1
( COL1, COL2) VALUES
(@COL1, @COL2)
Run Code Online (Sandbox Code Playgroud)
这适用于SqlClient.但是我使用抽象类System.Data( ,DbCommand,DbParameter等),并根据在App.config的连接字符串设置不同的数据提供商如Oracle,MySQL和Postgres的等.因此,我需要知道我必须使用哪个前缀.对于MS-SQL,它是@,Oracle使用的:,其余的我实际上不知道.
有没有办法从提供程序工厂获取此前缀字符?
System.Data.SqlClient.SqlClientFactory.Instance没有这样的信息或者至少我找不到它.
否则,你能给我一个公共数据库列表吗?
编辑:目标平台是.NET 2到.NET 4,信息应该通过提供程序工厂提供.
是否有任何方法可以指示C#忽略NullReferenceException(或任何特定的例外情况)一组语句.当尝试从可能包含许多空对象的反序列化对象中读取属性时,这很有用.有一个帮助方法来检查null可能是一种方法,但我正在寻找一个接近于'On Error Resume Next'(来自VB)的语句级别的块.
编辑:Try-Catch将跳过关于异常的后续语句
try
{
stmt 1;// NullReferenceException here, will jump to catch - skipping stmt2 and stmt 3
stmt 2;
stmt 3;
}
catch (NullReferenceException) { }
Run Code Online (Sandbox Code Playgroud)
例如:我将XML消息反序列化为对象,然后尝试访问类似的属性
Message.instance[0].prop1.prop2.ID
Run Code Online (Sandbox Code Playgroud)
现在prop2可能是一个空对象(因为它不存在于XML Message中 - XSD中的可选元素).现在我需要在访问叶元素之前检查层次结构中每个元素的null.即在访问"ID"之前,我要检查实例[0],prop1,prop2是否为空.
是否有更好的方法可以避免对层次结构中的每个元素进行空值检查?
我喜欢C#3.0.我最喜欢的部分之一是扩展方法.
我喜欢将扩展方法视为可应用于广泛类的实用程序函数.我被警告说这个问题是主观的,可能会被关闭,但我认为这是一个很好的问题,因为我们都有"样板"代码来做一些相对静态的事情,比如"用于XML的转义字符串" - 但我还没有找到收集这些的地方.
我对执行日志记录/调试/分析,字符串操作和数据库访问的常用函数特别感兴趣.某处有哪些类型的扩展方法库吗?
编辑:将我的代码示例移到答案中.(感谢Joel清理代码!)
我想要输出一个整数到罗马数字并由Jesse Slicer 运行这个答案.这是一种扩展方法,但我想知道如何利用ToString(string, IFormatProvider)这样做
int a = 10;
string b = a.ToString("RN", provider);
// OR
string c = string.Format(provider, "{0:RN} blah foo", a);
Run Code Online (Sandbox Code Playgroud)
代替
int a = 10;
string b = a.ParseRomanNumeral();
// OR
string c = string.Format("{0} blah foo", a.ParseRomanNumeral());
Run Code Online (Sandbox Code Playgroud)
我从来没有写过格式提供程序,所以我不确定所涉及的工作,但这是我的问题. 对于像罗马数字这样明确定义的格式转换,您会使用:
Parse,TryParse和ToString为什么?
使用string.Format()和它的任何堂兄方法(例如StringBuilder.AppendFormat())会影响你的答案吗?显然,使用扩展方法,您无法使用这些格式化方法之一访问转换.
我认为实现整个色域的自定义类将是最谨慎但也是最耗时的.使用自定义格式提供程序似乎会踩到一些现有全球化的东西(如果你有的话).
我有一个.NET应用程序.我需要将加密的文本值存储在文件中,然后在代码中的其他位置检索加密值并对其进行解密.
我不需要地球上最强大或最安全的加密方法,只需要说一些东西 - 我有加密的值,并且能够解密它.
我在网上搜索了很多以尝试使用密码术,但我发现的大多数例子都没有明确定义概念,最糟糕的是它们似乎是机器特定的.
从本质上讲,有人可以发送链接到易于使用的加密方法,该方法可以将字符串值加密到文件,然后检索这些值.
我有一个变量,其值在运行时填充.我想检查该值是否在两个相同的数据类型值(比如最低和最高)之间,或者是否使用扩展方法.
我想检查一下
int a = 2; //here static but is can be changed at runtime
if(a.Between(0,8))
DoSomething();
else
DoNothing();
Run Code Online (Sandbox Code Playgroud)
如果a是0或8或它们之间的任何值,它应该返回true.
如果a是(-1或更小)或(9或更大)那么它应该返回false
我想创建一个类似的扩展方法
public static bool Between<T1>(this T1 val1, T1 lowest, T1 highest) where ????
{
What code to write here????
}
Run Code Online (Sandbox Code Playgroud) c# ×9
.net ×4
.net-3.5 ×2
abstract ×1
ado.net ×1
asp.net ×1
boilerplate ×1
database ×1
encryption ×1
events ×1
exception ×1
factory ×1
locking ×1
parameters ×1
vb.net ×1