c# - ExtensionMethod 特定于类、属性或方法

标签 c# extension-methods

我更喜欢使用很多扩展方法,如ToFloat , ToInt , ToLoong , ToGuid , ToSqlParameter
现在,自从我一直在我现在的位置工作以来,有些人一直在提示他们在日常对象上看到的大量扩展方法。

对于我的问题,我将起诉示例:“ToSqlParameter”

    public static SqlParameter ToSqlParameter(this object source, string name, bool structured = false)
    {
        var para = new SqlParameter { ParameterName = name, Value = source };
        if (structured) { para.SqlDbType = SqlDbType.Structured; }
        return para;
    }

目前,每个对象都有可用的扩展方法。

我知道添加类似 where T : class 的内容只会让它在类上工作,但因为这个方法应该能够在 string 上使用, bool , 甚至 objects我对此无能为力。

现在我的问题是,是否可以创建扩展方法,以便它只能在应用于 List<SqlParameter> 时使用

喜欢 :
var str = "Some Strnig";
var list = new List<SqlParameter>();
var list2 = new List<string>();
list.Add(str.ToSqlParameter("@str")); //Should work
list2.Add(str.ToSqlParameter("@str")); //Should return 'SqlParameter not found'

这可能吗?

最佳答案

不,这是不可能的。

扩展方法仅因您尝试调用它们的类型而被发现,而不是基于周围的上下文。

您的最后一行代码会得到一个不同的错误,因为 ToSqlParameter 的结果无法添加到列表中,但该方法可用。

“过滤”扩展方法的唯一方法是:

  • 它们可以被调用的类型,这里不是一个选项,因为你想要它在 object
  • 按 namespace ,因此按您显式添加 using X; 的位置指令使其可用。

  • 另一方面,如果所有对象都可以简单地包装在 SqlParameter 中,那么这里有一种不同的方法,使用反射。

    这是一个原型(prototype)(未测试):
    public static void AddParameters(this SqlCommand command, object parameters)
    {
        foreach (var propertyInfo in parameters.GetType().GetProperties())
        {
            object propertyValue = propertyInfo.GetValue(parameters, null);
            command.Parameters.AddWithValue("@" + propertyInfo.Name, propertyValue);
        }
    }
    

    你会像这样使用它:
    public void DeletePersonById(int id)
    {
        var cmd = new SqlCommand();
        cmd.Connection = ...
        cmd.CommandText = "delete from persons where person_id = @id");
        cmd.AddParameters(new { id });
        cmd.ExecuteNonQuery();
        ...
    

    请注意,此方法仅创建非常基本的 SqlParameter对象,您可能希望扩展它以更好地处理特殊类型,例如具有大小的字符串等。

    有关我用于简单程序的一些基本代码的更完整示例,请查看此处:Dropbox link to SO16962113.linq .这是一个 LINQPad您可以运行的程序将在本地创建 SQL Server 数据库并为查询设置一些虚拟数据。

    相关语法(方法在 LINQPad 程序中实现):
    using (var conn = new SqlConnection("...").AutoOpen())
    {
        // prepare a fresh new database
        conn.Execute("if exists (select * from sysdatabases where name = 'SO16962113') drop database SO16962113");
        conn.Execute("create database SO16962113");
        conn.Execute("use SO16962113");
    
        // execute some queries
        conn.Execute("create table persons (person_id int primary key not null identity(1,1), person_name varchar(100))");
        conn.Execute("insert into persons (person_name) values ('James'), ('Jon'), ('Mary'), ('Jack')");
        conn.Query<Person>("select * from persons where person_id in (@id1, @id2)", new { id1 = 2, id2 = 4 }).Dump();
    
        // clean up
        conn.Execute("use master");
        conn.Execute("drop database SO16962113");
    }
    

    关于c# - ExtensionMethod 特定于类、属性或方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16962113/

    相关文章:

    c# - 是否有任何第三方库可以将 Postgresql 或 MySql 与 C# 一起使用,从而允许直接将对象转换为数据库?

    C# 单例模式在实现并行而不是并发处理后未按预期工作

    c# - 为什么扩展方法调用不明确?

    c# - 为什么不能从扩展类型的基类中调用扩展方法?

    Rust 等同于具有相同泛型参数约束的 Swift 扩展方法?

    c# - 在 Razor ASP.NET MVC 中调用方法

    c# - Web.config 运行时/legacyCorruptedStateExceptionsPolicy 设置不起作用

    c# - 如何在多个子类上返回不同的类型?

    .net - 用单行求和 TimeSpan 数组?

    c# - 如何编写返回动态对象的扩展方法?