- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在开发一个可以采用多种不同数据类型(任何实现 IComparable 的数据类型)的控件。
我需要能够将这些与传入的另一个变量进行比较。
如果主要数据类型是 DateTime,并且传递给我的是 String,我需要
所以我需要一种通用的方法来尝试从任何类型转换为任何类型。很简单,.Net 为我们提供了 TypeConverter类。
现在,要确定 String 是否可以转换为 DateTime,我能做的最好的事情就是使用异常。如果 ConvertFrom 引发异常,我知道我不能进行转换并且必须进行字符串比较。
以下是我得到的最好的:
string theString = "99/12/2009";
DateTime theDate = new DateTime ( 2009, 11, 1 );
IComparable obj1 = theString as IComparable;
IComparable obj2 = theDate as IComparable;
try
{
TypeConverter converter = TypeDescriptor.GetConverter ( obj2.GetType () );
if ( converter.CanConvertFrom ( obj1.GetType () ) )
{
Console.WriteLine ( obj2.CompareTo ( converter.ConvertFrom ( obj1 ) ) );
Console.WriteLine ( "Date comparison" );
}
}
catch ( FormatException )
{
Console.WriteLine ( obj1.ToString ().CompareTo ( obj2.ToString () ) );
Console.WriteLine ( "String comparison" );
}
我们的部分工作标准规定:
只有在出现异常情况时才应引发异常 - 即。遇到错误。
但这并不是特例。我需要另一种解决方法。
大多数变量类型都有一个 TryParse方法返回一个 bool 值,以允许您确定转换是否成功。但是 TypeConverter 没有可用的 TryConvert 方法。 CanConvertFrom如果可以在这些类型之间进行转换并且不考虑要转换的实际数据,则只进行 dermines。 IsValid方法也没有用。
有什么想法吗?
编辑
我不能使用 AS 和 IS。我在编译时不知道这两种数据类型。所以我不知道该怎么做!!!
编辑
确定了那个 SCSS 。它不像 Marc Gravells 那样整洁,但它确实有效(我希望如此)。感谢马克的灵感。我会在有空的时候整理它,但我有一些错误修复需要继续处理。
public static class CleanConverter
{
/// <summary>
/// Stores the cache of all types that can be converted to all types.
/// </summary>
private static Dictionary<Type, Dictionary<Type, ConversionCache>> _Types = new Dictionary<Type, Dictionary<Type, ConversionCache>> ();
/// <summary>
/// Try parsing.
/// </summary>
/// <param name="s"></param>
/// <param name="value"></param>
/// <returns></returns>
public static bool TryParse ( IComparable s, ref IComparable value )
{
// First get the cached conversion method.
Dictionary<Type, ConversionCache> type1Cache = null;
ConversionCache type2Cache = null;
if ( !_Types.ContainsKey ( s.GetType () ) )
{
type1Cache = new Dictionary<Type, ConversionCache> ();
_Types.Add ( s.GetType (), type1Cache );
}
else
{
type1Cache = _Types[s.GetType ()];
}
if ( !type1Cache.ContainsKey ( value.GetType () ) )
{
// We havent converted this type before, so create a new conversion
type2Cache = new ConversionCache ( s.GetType (), value.GetType () );
// Add to the cache
type1Cache.Add ( value.GetType (), type2Cache );
}
else
{
type2Cache = type1Cache[value.GetType ()];
}
// Attempt the parse
return type2Cache.TryParse ( s, ref value );
}
/// <summary>
/// Stores the method to convert from Type1 to Type2
/// </summary>
internal class ConversionCache
{
internal bool TryParse ( IComparable s, ref IComparable value )
{
if ( this._Method != null )
{
// Invoke the cached TryParse method.
object[] parameters = new object[] { s, value };
bool result = (bool)this._Method.Invoke ( null, parameters);
if ( result )
value = parameters[1] as IComparable;
return result;
}
else
return false;
}
private MethodInfo _Method;
internal ConversionCache ( Type type1, Type type2 )
{
// Use reflection to get the TryParse method from it.
this._Method = type2.GetMethod ( "TryParse", new Type[] { type1, type2.MakeByRefType () } );
}
}
}
最佳答案
泛型是一种选择吗?这是一个厚颜无耻的黑客攻击 TryParse
方法并通过(缓存的)委托(delegate)调用它:
using System;
using System.Reflection;
static class Program
{
static void Main()
{
int i; float f; decimal d;
if (Test.TryParse("123", out i)) {
Console.WriteLine(i);
}
if (Test.TryParse("123.45", out f)) {
Console.WriteLine(f);
}
if (Test.TryParse("123.4567", out d)) {
Console.WriteLine(d);
}
}
}
public static class Test
{
public static bool TryParse<T>(string s, out T value) {
return Cache<T>.TryParse(s, out value);
}
internal static class Cache<T> {
public static bool TryParse(string s, out T value)
{
return func(s, out value);
}
delegate bool TryPattern(string s, out T value);
private static readonly TryPattern func;
static Cache()
{
MethodInfo method = typeof(T).GetMethod(
"TryParse", new Type[] { typeof(string), typeof(T).MakeByRefType() });
if (method == null) {
if (typeof(T) == typeof(string))
func = delegate(string x, out T y) { y = (T)(object)x; return true; };
else
func = delegate(string x, out T y) { y = default(T); return false; };
} else {
func = (TryPattern) Delegate.CreateDelegate(typeof(TryPattern),method);
}
}
}
}
关于c# - 没有异常风险的通用类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2111280/
我有一个 Magento 网站,其中似乎没有出现交叉销售产品。 在查看 Stack 和 Google 之后,似乎“重新索引数据”已经为很多人解决了这个问题。 我的问题是,执行此任务是否有任何风险?或者
为了避免在某些简单命令中使用括号,我编写了以下运算符以创建新的图形窗口。我的问题是:除了明显无法在我的变量“ newdev”上执行“ not”功能之外,我是否有“破坏” R中任何内容的风险? # fu
你好 我正在开发一个联系表格。我正在使用邮件功能将其通过电子邮件发送给网站管理员。 是否存在有人可以注入(inject)恶意 javascript 和任何其他注入(inject)攻击的风险? $to
我想知道在 Objective C 中将消息传递给 nil 对象不会执行任何操作,这样依赖是否存在任何风险。 在我的代码中,我有很多对 UIKit 和其他对象的弱引用,这些引用可能随时被清除。由于我来
我被指派修复遗留代码的安全问题,并获得了安全扫描的结果: Poor Error Handling: Server Error Message ( 10932 ) 基本上,当扫描尝试使用一些奇怪的代码进
我有一个匿名类,在创建时需要使用自引用。我的业务代码可以简化为如下代码,我知道这段代码: final Runnable runnable=new Runnable() { @Override
有几个基类是我无法控制的:- class BaseNode // Just a POD class. No VTable { void foo(); } class BaseHost { publ
这个问题已经有答案了: Do I have to guard against SQL injection if I used a dropdown? (11 个回答) 已关闭 7 年前。 我希望我的网
这是根据用户提供的输入创建表的简单过程: PROCEDURE `hackProcedure`( IN tab_name VARCHAR(63)) BEGIN IF (tab_name REGEXP '
我知道在您的网站上显示用户输入时,使用 php 中的 htmlentities() 之类的函数来清理用户输入很有用。但是这样的事情会带来 XSS 风险吗? " /> 像这样清理输入会更好吗? " />
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
谁能阐明图表上曲线的含义、阴影区域的含义以及轴的含义? 最佳答案 这是对风险随时间变化的预测。在 NCrunch wiki 中有一些文档对此进行了描述:http://wiki.ncrunch.net/
我有一个包含 200 万条记录的集合,如果可能的话,我希望在不停机的情况下在其上添加单个字段索引。 我的问题是:是否可以/需要备份集合?使用 azure 门户创建索引在后台运行它而不会造成任何服务停机
我正在使用Symfony2并使用 CSRF token 保护我的表单。 我有一个基于 Ajax 调用的评论系统。如果用户想要编辑他的评论,则会发生以下情况: 用户点击编辑按钮。 通过 ajax 加载“
Checkmark 扫描了我们的代码并显示这些代码存在二阶注入(inject)的风险像这样的代码 @SuppressWarnings("unchecked") public List> findByS
我有一个包含几百行的小型 MySQL 数据库(全部为文本,无图像)。我正在使用 iQuery 请求所有行并在客户端进行所有过滤。 iQuery 代码如下: $(document).ready( fun
如果我的网站只允许用户查看他们自己提交的数据,而永远不允许其他用户提交的数据(即没有一般的“帖子”等)——那么我的网站是否真的存在 XSS 风险? 我仍将致力于 XSS 解决方案(如 httmlspe
我正在构建一个 iframe,而不是 innerHTML , 但带有 createElement .. 我使用了两个不受信任的字符串: iframeEl.title = untrustedStr1;
我正在生成如下动态prepareStatement(字段可能会根据请求输入而变化)。 Veracode 扫描持续报告 SQL 注入(inject)风险 - CWE-89:SQL 命令中使用的特殊元素的
我有一个可以在英语和德语之间切换语言的应用程序。当使用德语时,我希望货币显示将自动转换为德语格式。因此,在我的程序中,我必须检查区域设置,然后根据所选语言转换货币。我选择使用 locale.setDe
我是一名优秀的程序员,十分优秀!