c# 中是不是有 jQuery 扩展?

Posted

技术标签:

【中文标题】c# 中是不是有 jQuery 扩展?【英文标题】:Is there a jQuery extend in c#?c# 中是否有 jQuery 扩展? 【发布时间】:2014-11-27 04:35:51 【问题描述】:
 var _Contact = new ContactLstModel  
             ContactName="xxxxxx",
              EmailAddr="yyyyyy",
               ContactNo="ddddddd",
               SelectedContactType="dddd"
            ;

 var _ContactOption= new ContactLstModel
                 ContactType= new List<SelectListItem>()
                 new SelectListItem
                  Text="sss",Value="ddd"
                 
                 
            ;

如您所见,两者的型号相同ContactLstModel。现在如何将两者合二为一?

就像在 jQuery 中一样,我们有 $.extend(dest,source);

C# 中是否有等价物?

【问题讨论】:

【参考方案1】:

在 C# 和 .NET 4.5 中没有内置的 $.extend 等效项。

但是,您可以找到许多尝试在 .NET 中使用 reflection 实现这种行为的示例。还有其他人使用序列化(JSON.NET 等)来实现类似的行为。另一种方法是使用 IOC 容器,例如 Automapper。

这是一个如何使用Automapper IOC 将您的第一个对象合并到第二个对象的示例:

var expr = Mapper.CreateMap<ContactLstModel, ContactLstModel>().ForMember("ContactType", (conf) =>  conf.Ignore(); );
var merged = Mapper.Map<ContactLstModel, ContactLstModel>(_Contact, _ContactOption);

使用 Automapper,您可以控制如何将每个属性从源映射到目标。

如果您不想要外部库依赖,并且想要完全控制,您可以使用纯反射方法。

例如,您可以使用类似于 link 中的 CopyValues 方法的方法,并使用反射将第二个对象属性与第一个对象属性合并。

CopyValues<ContactLstModel>(_Contact, _ContactOption);

所以这行代码会将第二个对象的 ContactType 属性值复制到第一个对象中。

CopyValues 使用反射循环遍历对象的属性:

public static void CopyValues<T>(T target, T source)

    Type t = typeof(T);

    var properties = t.GetProperties().Where(prop => prop.CanRead && prop.CanWrite);

    foreach (var prop in properties)
    
        var value = prop.GetValue(source, null);
        if (value != null)
            prop.SetValue(target, value, null);
    

当然,这并不支持 jquery extend 所做的一切(合并、浅克隆和深层克隆到新对象等),但它可以满足您当前的需求。您可以扩展这些原则并构建更全面的解决方案。

但是请记住,C# 不像 javascript 那样是一门语言,在 C# 中进行反射的成本要高得多,而在 Javascript 中,原型的属性可以通过廉价的for-in 迭代列出,或者使用调用 Object.keys()。

【讨论】:

反射比专用于特定对象的方法(如 Tomas Lycken 的回答)要慢一些,并且控制较少,但它是实现这一目标的最通用方法。 是的。 JQuery 扩展自动合并属性而不指定名称,因此基于反射的方法可能是他能获得的最接近这种功能的方法。【参考方案2】:

您可以使用扩展方法来做到这一点:

public static class ContactModelExtensions 
    public static ContactModel Extend(this ContactModel first, ContactModel replacement) 
        if (!replacement.ContactsName.IsNullOrEmpty()) // or whatever criteria you want
        
            first.ContactsName = replacement.ContactsName;
        
        // similar assignment for all other properties

        return first; // since we return the first one, properties not set in override
                      // will be untouched
    

现在,你可以

var extendedContact = _Contact.Extend(_ContactOptions);

完成它。

【讨论】:

很好的命题,而且比反射更快,但是这个具体的例子肯定不会编译,因为“override”是一个保留关键字。我建议对其进行修改。 @Richard:谢谢。这就是我在没有测试的情况下输入代码的结果,我猜:P【参考方案3】:

您可以使用一些框架来做到这一点。例如ValueInjecter:

    public class NoNullsInjection : ConventionInjection
    
        protected override bool Match(ConventionInfo c)
        
            return c.SourceProp.Name == c.TargetProp.Name
                    && c.SourceProp.Value != null;
        
    

    class A
    
        public string a  get; set; 
        public string b  get; set; 
    

    static void Main(string[] args)
    
        A a1 = new A()  a = "123" ;
        A a2 = new A()  b = "456" ;
        A c = new A();

        c.InjectFrom(new NoNullsInjection(),a1,a2); 
        // "c" now have a="123", b="456"     

    

【讨论】:

以上是关于c# 中是不是有 jQuery 扩展?的主要内容,如果未能解决你的问题,请参考以下文章

在 Chrome 扩展中被覆盖的新选项卡中使用 jQuery 是不是违反了内容安全策略?

扩展 C# .NET 应用程序 - 是不是构建自定义脚本语言?

c#基于值而不是引用调度扩展方法

如何扩展存储在变量中的 jQuery 选择器?

JavaScript 等效于 jQuery 的扩展方法

jquery插件与扩展一