【问题标题】:Question about var type关于var类型的问题
【发布时间】:2009-07-01 05:31:23
【问题描述】:

我是 C# 3.0 var 类型的新手。在这里,我有一个关于这种类型的问题。以库中的以下简单代码为例:

 public class MyClass {
    public var Fn(var inValue)
    {
        if ( inValue < 0 )
        {
           return 1.0;
        }
        else 
        { 
           return inValue;
        }
    }
 }

我认为参数是匿名类型。如果我传入一个浮点值,那么 Fn 应该返回一个浮点类型。如果传入一个double值类型,Fn会返回一个double类型吗?整数值类型作为输入值怎么样?

实际上,我想将 var 类型与此函数/方法一起使用,以动态获取具有各种输入类型的不同返回类型。不知道这个用法对不对?

【问题讨论】:

  • 我的代码可能有误。我阅读了一些关于在本地范围内使用 var 的文章,但没有在库中作为公共方法的 var 类型。不确定,因为我没有 VS 来验证它。

标签: c#-3.0


【解决方案1】:

您不能将var 用于返回值或参数类型(或字段)。您只能将它用于局部变量。

Eric Lippert 有一个blog post about why you can't use it for fields。我不确定返回值和参数类型是否有类似的。参数类型当然没有多大意义——编译器从哪里推断出类型?您尝试对参数调用什么方法? (实际上 F# 差不多就是这样,但 C# 更保守。)

不要忘记var 是严格 静态类型 - 它只是让编译器为您推断静态类型的一种方式。它仍然只是一种类型,就像您在代码中输入了名称一样。 (当然,对于匿名类型,您不能这样做,这是该功能的一个动机。)

编辑:有关var 的更多详细信息,您可以在Manning's site 免费下载C# 的第8 章-这包括var 部分。显然我希望你会想买这本书,但没有压力:)

编辑:为了解决您的实际目标,您几乎可以使用通用方法实现所有这些:

public class MyClass
{
    public T Fn<T>(T inValue) where T : struct
    {
        Comparer<T> comparer = Comparer<T>.Default;
        T zero = default(T);
        if (comparer.Compare(inValue, zero) < 0)
        {
            // This is the tricky bit.
            return 1.0;
        }
        else 
        { 
            return inValue;
        }
    }
}

如清单所示,棘手的一点是找出“1”对于任意类型的含义。你可以硬编码一组值,但这有点难看:

public class MyClass
{
    private static readonly Dictionary<Type, object> OneValues
        = new Dictionary<Type, object>
    {
        { typeof(int), 1 },
        { typeof(long), 1L },
        { typeof(double), 1.0d },
        { typeof(float), 1.0f },
        { typeof(decimal), 1m },
    };

    public static T Fn<T>(T inValue) where T : struct
    {
        Comparer<T> comparer = Comparer<T>.Default;
        T zero = default(T);
        if (comparer.Compare(inValue, zero) < 0)
        {
            object one;
            if (!OneValues.TryGetValue(typeof(T), out one))
            {
                // Not sure of the best exception to use here
                throw new ArgumentException
                    ("Unable to find appropriate 'one' value");
            }
            return (T) one;
        }
        else 
        { 
            return inValue;
        }
    }
}

恶心 - 但它会工作。然后你可以写:

double x = MyClass.Fn(3.5d);
float y = MyClass.Fn(3.5f);
int z = MyClass.Fn(2);

等

【讨论】:

  • 哈,今晚我赢了你两次。这不会经常发生。不过,我会等待您的出色编辑:)
  • 对不起,约翰,我会给“优秀的编辑”打分,但也为你的幽默+1 :)
【解决方案2】:

您不能使用 var 作为方法的返回类型。

【讨论】:

  • 太糟糕了,我猜。不像 Ruby 或 Python。没关系。谢谢!
  • @David:这些是动态语言。如果您不喜欢静态类型,那么您在 C# 中不会有太多乐趣。尽管 C# 4 引入了动态类型,但我只会在您真正需要的地方使用它。 C# 是围绕静态类型构建的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-05
  • 2011-11-04
  • 2011-05-14
  • 2017-09-29
  • 2013-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多