对 ValueTypes、Strings 和 ValueTypes 的 Nullable 的通用约束

发布于 2024-07-16 19:53:06 字数 1205 浏览 3 评论 0 原文

我正在尝试向通用方法添加约束,以便它检查 ValueTypes、Strings 或 Nullable 值类型。

问题在于:

  • 值类型是 struts
  • 字符串是不可变的引用类型
  • 可空是值类型,但在“where S : struct”类型约束中不会被接受。

那么有人知道是否有一种方法可以让我在通用约束中接受这些且仅接受这些类型?

问题是我试图接受一个 Expression 参数,该参数将表示给定对象的这些类型的属性。

功能将类似于以下内容(请注意,代码没有任何意义,只是快速了解我正在寻找的内容):

public class Person
{
   public string Name {get; set;}
   public DateTime? DOB {get; set;}
   public int NumberOfChildren {get; set;}
   public Car CurrentCar {get; set;}
}

---

internal void MyGenericMethod<T, S>(T myObject, Expression<Func<T, S> property){...}

Person myPerson = new Person();
MyGenericMethod(myPerson, p => p.Name); //S would be a string
MyGenericMethod(myPerson, p => p.DOB); //S would be a DateTime? 
MyGenericMethod(myPerson, p => p.NumberOfChildren); //S would be a struct

上面的三个调用都应该被接受,但不应该接受以下调用:

MyGenericMethod(myPerson, p => p.CurrentCar); //S would be a class and shouldn't compile

提前致谢

更新:谢谢安东和马克。 MyGenericMethod 有 4 个不同的签名接受额外的参数,这就是为什么我不喜欢为现有 4 个中的每一个创建 3 个不同的(结构体、可空、字符串)的想法......维护起来将是一场噩梦!

I'm trying to add a constraint to a generic method so it checks for ValueTypes, Strings or Nullable value types.

The problem is that:

  • value types are struts
  • strings are immutable reference types
  • nullable are value types but won't be accepted in a "where S : struct" type constraint.

So does anybody know if there's a way I can accept these and only these types in a generic constraint?

The problem is I'm trying to accept an Expression<Func<T, S> parameter that will represent a property of these types for a given object.

The functionality would be something like the following (note the code doesn't make any sense and is just something quick to get an idea of what I'm looking for):

public class Person
{
   public string Name {get; set;}
   public DateTime? DOB {get; set;}
   public int NumberOfChildren {get; set;}
   public Car CurrentCar {get; set;}
}

---

internal void MyGenericMethod<T, S>(T myObject, Expression<Func<T, S> property){...}

Person myPerson = new Person();
MyGenericMethod(myPerson, p => p.Name); //S would be a string
MyGenericMethod(myPerson, p => p.DOB); //S would be a DateTime? 
MyGenericMethod(myPerson, p => p.NumberOfChildren); //S would be a struct

The three calls above should all be accepted, but not the following:

MyGenericMethod(myPerson, p => p.CurrentCar); //S would be a class and shouldn't compile

Thanks in advance

UPDATE: Thanks Anton and Marc. MyGenericMethod has 4 different signatures accepting extra parameters, that's why I don't like the idea of creating 3 different (struct, nullable, string) for each of the existing 4... that would be a nightmare to maintain!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

温折酒 2024-07-23 19:53:06

我唯一能想到的是一组三个函数(无 Expression>> 之类的东西):

MyGenericFunction<T>(T t)
    where T : struct

MyGenericFunction<T>(T? t)
    where T : struct

MyGenericFunction(string s)

UPDATE 鉴于方法有各种重载,我可以建议:

class Holder
{
    private object value;

    public Holder(object value)
    {
        this.value = value;
    }

    public static implicit operator Holder(DateTime dt)
    {
        return new Holder(dt);
    }

    public static implicit operator Holder(string s)
    {
        return new Holder(s);
    }

    // Implicit conversion operators from primitive types
}

因此你的方法变得

MyGenericMethod(Holder h);

仍然非常麻烦,但无论如何它可能会奏效。

The only thing I can come up with is a set of three functions (sans Expression<> stuff):

MyGenericFunction<T>(T t)
    where T : struct

MyGenericFunction<T>(T? t)
    where T : struct

MyGenericFunction(string s)

UPDATE Given that there are various overloads of a method, I can suggest:

class Holder
{
    private object value;

    public Holder(object value)
    {
        this.value = value;
    }

    public static implicit operator Holder(DateTime dt)
    {
        return new Holder(dt);
    }

    public static implicit operator Holder(string s)
    {
        return new Holder(s);
    }

    // Implicit conversion operators from primitive types
}

Thus your method becomes

MyGenericMethod(Holder h);

Still very cumbersome, but nevertheless it might work out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文