You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何让类的Func属性引用其未知(或不关心)的类型?

解决方案:让类的Func属性支持未知类型

在C#场景中,若希望类的Func类型属性能引用其无需关心的未知类型(比如项目A无需了解Person类型,仅需提供可由使用者自定义的筛选器逻辑),以下是可行的解决方案:

方案一:将类定义为泛型类

把MyListType改为泛型类,由调用方指定具体类型T,项目A无需知晓T的具体实现,仅负责维护筛选器的存储逻辑。

项目A代码

// Project A 无需知道具体T类型
public class MyListType<T>
{
    public MyListType(string listName)
    {
        ListName = listName;
    }

    public string ListName { get; set; }
    public Func<List<T>, List<T>> Filter { get; private set; }

    public MyListType<T> WithFilter(Func<List<T>, List<T>> filter)
    {
        Filter = filter;
        return this;
    }
}

项目B代码

public class Person
{
    public Person(string name)
    {
        Name = name;
    }
    public string Name { get; set; }
}

public class ClassB1
{
    public void TestFilter()
    {
        var beginsWithA = new MyListType<Person>("Begins with 'A'")
            .WithFilter(persons => persons.Where(p => p.Name.StartsWith("A")).ToList());

        var people = new List<Person>
        {
            new Person("Alan"), new Person("Alison"), new Person("Blinky"),
            new Person("Beatrice"), new Person("Xavier"), new Person("Zebedee")
        };

        var aPeople = beginsWithA.Filter(people);
    }
}

方案二:非泛型接口 + 泛型实现

若需隐藏泛型细节,可定义非泛型接口作为抽象层,内部用泛型类实现具体逻辑。项目A仅暴露非泛型接口,同时保留类型安全。

项目A代码

// 非泛型接口,项目A仅需维护此抽象层
public interface IListFilter
{
    string ListName { get; }
    object ExecuteFilter(object list);
}

// 泛型实现类,项目A内部维护
public class ListFilter<T> : IListFilter
{
    public ListFilter(string listName)
    {
        ListName = listName;
    }

    public string ListName { get; set; }
    private Func<List<T>, List<T>> _filter;

    public ListFilter<T> WithFilter(Func<List<T>, List<T>> filter)
    {
        _filter = filter;
        return this;
    }

    public object ExecuteFilter(object list)
    {
        if (list is List<T> typedList && _filter != null)
        {
            return _filter(typedList);
        }
        throw new ArgumentException("传入的列表类型不匹配");
    }
}

// 提供入口方法,隐藏泛型细节
public static class ListFilterFactory
{
    public static ListFilter<T> Create<T>(string listName)
    {
        return new ListFilter<T>(listName);
    }
}

项目B代码

public class ClassB1
{
    public void TestFilter()
    {
        var beginsWithA = ListFilterFactory.Create<Person>("Begins with 'A'")
            .WithFilter(persons => persons.Where(p => p.Name.StartsWith("A")).ToList());

        var people = new List<Person>
        {
            new Person("Alan"), new Person("Alison"), new Person("Blinky"),
            new Person("Beatrice"), new Person("Xavier"), new Person("Zebedee")
        };

        // 执行后转换回目标类型
        var aPeople = (List<Person>)beginsWithA.ExecuteFilter(people);
    }
}

方案三:使用动态类型(不推荐)

若可接受放弃编译时类型检查,可使用dynamic存储筛选器。此方式虽无需关心类型,但会丢失类型安全,增加运行时错误风险。

项目A代码

public class MyListType
{
    public MyListType(string listName)
    {
        ListName = listName;
    }

    public string ListName { get; set; }
    public dynamic Filter { get; private set; }

    public MyListType WithFilter(dynamic filter)
    {
        Filter = filter;
        return this;
    }
}

项目B代码

public class ClassB1
{
    public void TestFilter()
    {
        var beginsWithA = new MyListType("Begins with 'A'")
            .WithFilter((Func<List<Person>, List<Person>>)(persons => persons.Where(p => p.Name.StartsWith("A")).ToList()));

        var people = new List<Person>
        {
            new Person("Alan"), new Person("Alison"), new Person("Blinky"),
            new Person("Beatrice"), new Person("Xavier"), new Person("Zebedee")
        };

        var aPeople = beginsWithA.Filter(people);
    }
}

总结

优先选择方案一(泛型类),它既保证编译时类型安全,又让项目A无需关心具体类型;方案二适合需要隐藏泛型细节的场景;方案三仅作临时替代,不推荐用于正式业务逻辑。

内容的提问来源于stack exchange,提问作者komodosp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 14:03:17