我不理解RFC 6455中"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"的含义.为什么服务器需要这个神奇的字符串?为什么WebSocket协议需要这种机制?
我经常编写C#代码,必须使用魔术字符串来表达属性名称.每个人都知道魔术弦的问题.它们很难重构,它们没有编译时检查,并且通常会导致难以诊断的问题.然而,C#/ .NET 在整个地方使用它们来表示属性/类/方法名称.
这个问题已持续多年和多年,目前唯一可行的解决方案是使用表达式树,然后在运行时解析属性名称.这使您获得令人满意的编译时检查,但它使代码复杂化(需要Expression类型的参数),并且会产生运行时成本.
有没有人知道是否有一个特性考虑因为C#/ .NET添加编译时反射来克服这个普遍存在的问题?
看起来这将是一个简单的补充,它将是一个非破坏性的变化,它将使许多开发人员受益匪浅.typeof()运算符已经执行了编译时反射的形式,因此看起来运算符nameof()(或类似的东西)将非常互补.
此外,有没有人知道这个功能的任何潜在问题?
谢谢您的帮助.
我有桌面软件开发的背景,我开始学习ASP.NET MVC.
在我的默认HomeController中,我有Index动作,其代码如下所示:
if (!Request.IsAuthenticated)
return RedirectToAction("Login", "Account");
Run Code Online (Sandbox Code Playgroud)
换句话说,将用户重定向到"/ account/login".然后,AccountController.Login操作将处理用户并在他成功登录后将其发送回HomeController.
这段代码对我来说很有趣,也许只是因为我习惯于在桌面软件中做不同的事情.如果我将登录操作的名称更改为"LogOn"怎么办?如果我完全删除AccountController并用其他东西替换它会怎么样?我将介绍一个新的bug,但我不会遇到编译器错误,我的单元测试可能也不会捕获它.由于我使用字符串来指定控制器和动作名称,因此重构和重新设计更有可能在整个地方破坏代码.
我想要的是这样的:
if (!Request.IsAuthenticated)
return RedirectToAction(() => AccountController.Login);
Run Code Online (Sandbox Code Playgroud)
但是我不确定这是否可能,或者它是否是最好的方法.
我是愚蠢的,还是有其他人有同样的问题?你怎么做才能绕过它?
在工作代码中,我们有许多魔术字符串的使用,如下面的代码片段:
if (user.HasRight("Profile.View")) {...}
Run Code Online (Sandbox Code Playgroud)
因此,有很多地方我们将字符串作为参数传递,以查看用户是否具有特定权限.我不喜欢这样,因为它产生了很多神奇的字符串.
做一个更好的方法是什么?
Enum,Constant,class?
我有以下问题:我有一组引擎自动(听事件)控制我的模型.下图一般显示了类图:

现在我有一个知道EngineFacade的客户端,我想从客户端设置属性Active从Engine2,但客户端和EngineFacade都不知道三个引擎中的哪一个是Engine2.
有两种方法,但我不喜欢它们中的任何一种:
我在客户端网站上所知道的是,有一个或者应该是一个关注网格的引擎.但我不知道更多.
也许我必须在两个恶魔之间做出选择,但也许你们其中一个人有更好的解决方案.
我确定我已经看过这种语法
<%= Url.Action((MyController c) => c.MyMethod("a")) %>
Run Code Online (Sandbox Code Playgroud)
或类似的东西,作为在没有魔术字符串的ASP.net MVC中生成动作URL的方法.但是,我找不到Action过载.我有ASP.NET MVC 1.0.它在哪里?
我的WPF项目将按如下方式组织:
Screens
Group1
Screen1
View.xaml
ViewModel.cs
Group2
Screen2
View.xaml
ViewModel.cs
Run Code Online (Sandbox Code Playgroud)
要显示Screen1来自Screen2我将使用这样的东西:ScreenManager.Show("Group1.Screen1")这在Screens.Group1.Screen1View和ViewModel 的命名空间中查找(使用反射)并实例化它们.
我怎样才能消除魔法字符串,不耦合Screen1和Screen2(我不想班Screen2使用的Screen1命名空间).我也想要一些屏幕发现(自动完成/智能感知)
或者可能采用某种方式(自动化测试)来验证所有调用ScreenManager.Show是否有效.
更新: 我想出了这个:
public class ScreenNames
{
public Group1Screens Group1;
public class Group1Screens
{
public ScreenName Screen1;
}
}
public sealed class ScreenName
{
private ScreenName() { }
}
public class ScreenManager : IScreenManager
{
public void Show(Expression<Func<ScreenNames, ScreenName>> x) {}
}
Run Code Online (Sandbox Code Playgroud)
用法:
screenManager.Show(x=>x.Group1.Screen1);
Run Code Online (Sandbox Code Playgroud)
不理想,但我认为违反DRY仍然比魔术弦更好.我可以自动测试(通过反射)所有调用都是有效的.
我正在编写一个服务来获取特定类型的对象集合,并将其原始,字符串和日期时间类型输出为CSV格式的字符串.我有以下两个陈述都有效.我发现基于lambda的版本更清洁.
魔术弦版
string csv = new ToCsvService<DateTime>(objs)
.Exclude("Minute")
.ChangeName("Millisecond", "Milli")
.Format("Date", "d")
.ToCsv();
Run Code Online (Sandbox Code Playgroud)
与Lambda版本
string csv = new ToCsvService<DateTime>(objs)
.Exclude(p => p.Minute)
.ChangeName(p => p.Millisecond, "Milli")
.Format(p => p.Date, "d")
.ToCsv();
Run Code Online (Sandbox Code Playgroud)
根据Jon Skeet的建议,所有lambda方法都共享一个类似的方法签名
public IToCsvService<T> Exclude<TResult>(
Expression<Func<T, TResult>> expression)
Run Code Online (Sandbox Code Playgroud)
然后我传递expression.Body给FindMemberExpression.我已经从nhlambdaextensions项目FindMemberExpression的ExpressionProcessor.cs方法中修改了代码.我非常相似的版本如下:FindMemberExpression
private string FindMemberExpression(Expression expression)
{
if (expression is MemberExpression)
{
MemberExpression memberExpression = (MemberExpression)expression;
if (memberExpression.Expression.NodeType == ExpressionType.MemberAccess
|| memberExpression.Expression.NodeType == ExpressionType.Call)
{
if (memberExpression.Member.DeclaringType.IsGenericType
&& memberExpression.Member.DeclaringType …Run Code Online (Sandbox Code Playgroud) 我正在编写一个系统,它是程序员应用程序的基础,需要检测他们对某些数据的访问.我几乎可以使用属性这样做,如下所示:
public class NiceClass {
public int x { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后我进入并调整get和set访问器,以便他们适当地处理访问.但是,这要求用户(应用程序编程人员)将其所有数据定义为属性.
如果用户想要使用具有"正常"字段的预先存在的类(而不是属性),我无法检测到这些访问.例:
public class NotSoNiceClass {
public int y;
}
Run Code Online (Sandbox Code Playgroud)
我无法检测到访问y.但是,我想允许使用预先存在的类.作为折衷方案,用户有责任在访问此类数据时通知我.例如:
NotSoNiceClass notSoNice;
...
Write(notSoNice.y, 0); // (as opposed to notSoNice.y = 0;)
Run Code Online (Sandbox Code Playgroud)
这样的事情.相信我,我已经非常彻底地研究了这一点,甚至直接分析字节码以检测访问因可能的间接性等而不可靠.我确实需要用户通知我.
现在我的问题是:你能推荐一种"优雅"的方式来执行这些通知吗?(是的,我知道这种情况一开始并不"优雅";我试图不让它变得更糟;)).你会怎么做?
这对我来说是个问题,因为实际上情况是这样的:我有以下课程:
public class SemiNiceClass {
public NotSoNiceClass notSoNice { get; set; }
public int z { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
如果用户想要这样做:
SemiNiceClass semiNice;
...
semiNice.notSoNice.y = 0;
Run Code Online (Sandbox Code Playgroud)
他们必须做这样的事情:
semiNice.Write("notSoNice").y = 0;
Run Code Online (Sandbox Code Playgroud)
哪里Write会返回克隆 …
我现在写了几个自定义模型绑定器,并意识到我已陷入依赖魔术字符串的陷阱,例如:
if (bindingContext.ValueProvider.ContainsPrefix("PaymentKey"))
{
paymentKey = bindingContext.ValueProvider.GetValue("PaymentKey").AttemptedValue;
}
Run Code Online (Sandbox Code Playgroud)
我希望能够使用表达式强类型化前缀名称,但无法弄清楚如何,并将感谢一些帮助.
谢谢.
我有下一段代码:
internal static string GetNetBiosDomainFromMember(string memberName)
{
int indexOf = memberName.IndexOf("DC=", StringComparison.InvariantCultureIgnoreCase);
indexOf += "DC=".Length;
string domaninName = memberName.Substring(indexOf, memberName.Length - indexOf);
if (domaninName.Contains(","))
{
domaninName = domaninName.Split(new[] { "," }, StringSplitOptions.None)[0];
}
return domaninName;
}
Run Code Online (Sandbox Code Playgroud)
我正在为AD做一些解析,所以我有一些字符串,如"DC =","objectCategory =","LDAP://",",","." 谁谁.我发现上面的代码比下面的代码更具可读性:(你可能会发现反对,让我知道.)
private const string DcString = "DC=";
private const string Comma = ",";
internal static string GetNetBiosDomainFromMember(string memberName)
{
int indexOf = memberName.IndexOf(DcString, StringComparison.InvariantCultureIgnoreCase);
indexOf += DcString.Length;
string domaninName = memberName.Substring(indexOf, memberName.Length - indexOf);
if (domaninName.Contains(CommaString))
{
domaninName = domaninName.Split(new[] { …Run Code Online (Sandbox Code Playgroud) T4MVC是ASP.NET MVC应用程序的T4模板,它创建强类型帮助程序,在引用控制器,操作和视图时不使用文字字符串.
我只是想知道在Web.config文件中的应用程序设置是否可以有类似的东西:
<appSettings>
<add key="SecurityGuardEmailFrom" value="info@email.net" />
<add key="PasswordExpiresInDays" value="1" />
<add key="NumberOfPasswordsToKeep" value="5" />
</appSettings>
Run Code Online (Sandbox Code Playgroud)
所以,而不是这个:
private static readonly int PasswordExpiresInDays =
int.Parse(ConfigurationManager.AppSettings["PasswordExpiresInDays"]);
Run Code Online (Sandbox Code Playgroud)
我们有这样的事情:
MVC.Webconfig.PasswordExpiresInDays
Run Code Online (Sandbox Code Playgroud)
要么
MVC.AppSettings.PasswordExpiresInDays
Run Code Online (Sandbox Code Playgroud)
这将有助于在编译时检查应用程序设置是否仍在那里避免运行时错误.
这甚至可行吗?如果是的话,你知道是否已经在某处实现了类似的东西吗?
magic-string ×12
c# ×5
asp.net-mvc ×4
.net ×2
compile-time ×2
lambda ×2
action ×1
appsettings ×1
architecture ×1
casting ×1
coding-style ×1
csv ×1
field ×1
guid ×1
identifier ×1
mvvm ×1
refactoring ×1
t4mvc ×1
websocket ×1
wpf ×1