使用通用逻辑扩展C#接口而不使用扩展方法

And*_*ott 2 .net c# extension-methods interface c#-4.0

有没有办法在不使用扩展方法的情况下扩展接口?

如果我用一些get/set字符串定义一些接口,例如:

public interface IMyItem
{
    string Title { get; set; }
    string Description { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我想为这些接口添加一些简单的验证,但不必重新定义逻辑或强制某种形式的继承.

目前我正在使用扩展方法,如下所示:

public static class MyItemExtensions
{
    public static bool ERROR(this IMyItem item)
    {
        return item.TITLE_ERROR() || item.DESCRIPTION_ERROR();
    }

    public static bool TITLE_ERROR(this IMyItem item)
    {
        return string.IsNullOrEmpty(item.Title);
    }

    public static bool DESCRIPTION_ERROR(this IMyItem item)
    {
        return string.IsNullOrEmpty(item.Description);
    }
}
Run Code Online (Sandbox Code Playgroud)

这样做有用,我可以:

public class Item : IMyItem
{
   public string Title { get; set; }
   public string Description { get; set; }
}

public static class app
{
    public static void go()
    {
        var item = new Item
        {
            Title = "My Item Title", 
            Description = ""
        };

        Console.log(item.ERROR());
    }
}
Run Code Online (Sandbox Code Playgroud)

但我更喜欢ERROR,TITLE_ERROR&DESCRIPTION_ERROR get get/sets - 有没有办法实现相同但暴露Get/Set属性而不是扩展方法?

更新11/06/2014

正如许多人所建议的那样,abstract基于该示例,类将是一个明显的解决方案,但类型需要实现多个接口.

虽然可以安排继承,但这是对类型的不必要的复杂性和限制.

使用扩展方法在这些接口上进行验证的额外好处允许通过命名空间使用特定于上下文和共享的逻辑.

ERROR(this IMyItem item)可以在不同的命名空间上为接口定义多个扩展方法.一,检查无论是TITLE_ERRORDESCRIPTION_ERROR与另一个属性可能只测试一个.然后,根据上下文,可以引用相关的命名空间,并执行该项的共享验证.

我将看看微软的验证器,但它看起来相当冗长,我真的希望这些状态作为类型的属性,因为它使使用它们的代码更容易使用.

此外,这些是非常简单的示例,一些验证要复杂得多,有些情况需要与其他Web服务交互 - 尽管AppDomain中的Web服务数据缓存.

目前,这些interface扩展方法感觉是最好的解决方案.

Yuv*_*kov 5

我认为一个合适的解决方案是使用一个abstract class而不是一个interface.

您在这里分享的是一个通用的验证逻辑,它对任何实现的类都有效IMyItem.因此,我建议您创建一个abstract class作为所有项目的基础,这样他们就可以重用该验证代码.您甚至可以将这些属性设置为虚拟,因此可以扩展该验证代码:

public abstract class ItemBase : IMyItem
{
    public string cTitle { get; set; }
    public string cDescription { get; set; }

    public virtual bool Error 
    { 
      get { return TitleError || DescriptionError; } 
    }

    public virtual bool TitleError 
    { 
      get { return string.IsNullOrEmpty(cTitle); } 
    }

    public virtual bool DescriptionError 
    { 
      get { return string.IsNullOrEmpty(cDescription); } 
    }
}
Run Code Online (Sandbox Code Playgroud)