1

当条件(pred)对其一个类成员(值)成立时,我想更新一个对象列表(mycapsule,还有许多其他成员)。每当我改变某件事时,另一件事就失败了,我是 C# 的新手,真的很困惑。有人可以修复我的代码吗:在最好的情况下,我只会收到此错误,但我认为我的代码中缺少很多东西

The type or namespace name `T' could not be found. Are you missing a using directive or an assembly reference?

这是我的代码

using System;
using System.Collections.Generic ;
namespace test
{
    class MainClass
    {
        public static List< mycapsule<int,double> > sample=  new List< mycapsule<int,double>>();
        public static void Main (string[] args)
        {

            sample.Add(new mycapsule<int,double> {id=1 , value= 1.2});
            update(pred, 12.3);
        }

        public static bool pred(double x)
        {
            if (x==2.5) return true;
            return false;
        }
        public class mycapsule<KT, T>
        {
            public KT id {get ; set; } 
            public T value { get ; set; }
            public int p; // and more

        }    

        public bool update(Func<T, bool> predicate, T i)
        {
            foreach (var x in sample.FindAll(item => predicate(JustValue(item))) )
            {
                x.value = i ;
            }
            return true ;
        }



        public T JustValue(mycapsule<int,T> i)
        {
            return i.value;
        }

    }
}
4

3 回答 3

2

看看你的更新方法:

public bool update(Func<T, bool> predicate, T i)
{
    foreach (var x in KeyRecord.FindAll(item => predicate(JustValue(item))) )
    {
        x.value = i ;
    }
    return true ;
}

你希望T在这里做什么?该方法不是通用的(它没有写为update<T>),也没有在通用类中声明。

可能只想:

public bool update<T>(Func<T, bool> predicate, T i)

......但很难说不知道是什么KeyRecord.FindAll样子。哦,你也有同样的问题JustValue

作为一个附带问题,方法名称不遵循 .NET 命名约定,并且update在描述性方面是一个糟糕的方法名称。也不遵循 .NET 命名约定。这些东西在可读性方面真的很重要predJustValuemycapsule

于 2012-09-07T08:59:27.660 回答
0

试试这个,对于泛型方法,您使用的方法定义不正确。
它应该是

//MethodName<T,U>(T para1, U para2)

我已经更改了代码以包含反射,这应该可以工作。请尝试并提供反馈。

using System;
using System.Collections.Generic;
using System.Reflection;
namespace test
{
    class MainClass
    {
        public static List<Mycapsule<int, double>> sample = new List<Mycapsule<int, double>>();

        public static void Main(string[] args)
        {

            sample.Add(new Mycapsule<int, double> { id = 1, value = 1.2 });
            update(pred, 12.3);
        }

        public static bool pred(double x)
        {
            if (x == 2.5) return true;
            return false;
        }

        public static bool update<T>(Func<T, bool> predicate, T i)
        {
            var myCollection = sample.FindAll(p => pred(JustValue<double>(p)));
            MainClass mainClass = new MainClass();
            foreach (var x in myCollection)
            {
                MethodInfo changeTypeMethod = typeof(MainClass).GetMethod("GetValue");
                object value = changeTypeMethod.Invoke(mainClass, new object[] { i, typeof(T) });
                PropertyInfo valueProperty = x.GetType().GetProperty("value");
                valueProperty.SetValue(x, value);
            }
            return true;
        }

        public T GetValue<T>(T i)
        {
            return (T)Convert.ChangeType(i, typeof(T));
        }

        public static T JustValue<T>(Mycapsule<int, T> i)
        {
            return i.value;
        }
    }
    //Outside the MainClass inside the same namespace 
    public class Mycapsule<KT, T>
    {
        public KT id { get; set; }
        public T value { get; set; }
        public int p; // and more   

    }
}
于 2012-09-07T09:09:09.327 回答
0

由于类型安全原因,恐怕这不起作用。我尽可能地更正了代码并得到了这个:

public static List<mycapsule<int, double>> sample = new List<mycapsule<int, double>>();
public static void Main(string[] args)
{
    sample.Add(new mycapsule<int, double> { id = 1, value = 1.2 });
    update(pred, 12.3);
}

public static bool pred(double x)
{
    if (x == 2.5) return true;
    return false;
}

public class mycapsule<KT, T>
{
    public KT id { get; set; }
    public T value { get; set; }
    public int p; // and more
}

public static bool update<T>(Func<T, bool> predicate, T i)
{
    List<mycapsule<int, double>> list = sample.FindAll(item => predicate(JustValue(item)));
    foreach (var x in list)
    {
        x.value = i;
    }
    return true;
}

public static T JustValue<T>(mycapsule<int, T> i)
{
    return i.value;
}

错误是:

predicate(JustValue(item)) => Argument 1: cannot implicitly convert from double to T

这是因为您试图强制调用您指定为采用泛型类型T( Func<T, bool>) 的方法,该方法的值已知为double. 虽然我们知道T调用 to 会加倍update(pred, 12.3);,但没有什么能阻止我传入一个采用不兼容类型的谓词,例如:

public static bool pred(string x)
{
    return false;
}

update(pred, "asdf");

这显然是不一致的。编译器只是试图防止你不小心射中自己的脚。

为了解决这个问题,您可以显式地将集合传递给 update method,从而确保类型是一致的:

public static List<mycapsule<int, double>> sample = new List<mycapsule<int, double>>();
public static void Main(string[] args)
{
    sample.Add(new mycapsule<int, double> { id = 1, value = 1.2 });
    update(pred, 12.5, sample);
}

public static bool pred(double x)
{
    if (x == 2.5) return true;
    return false;
}

public class mycapsule<KT, T>
{
    public KT id { get; set; }
    public T value { get; set; }
    public int p; // and more
}

public static bool update<T>(Func<T, bool> predicate, T i, List<mycapsule<int, T>> list)
{
    foreach (var x in list.FindAll(item => predicate(JustValue(item))))
    {
        x.value = i;
    }
    return true;
}

public static T JustValue<T>(mycapsule<int, T> i)
{
    return i.value;
}
于 2012-09-07T09:30:09.683 回答