Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在泛型IEnumerable中设置值_C#_Generics_Ienumerable - Fatal编程技术网

C# 在泛型IEnumerable中设置值

C# 在泛型IEnumerable中设置值,c#,generics,ienumerable,C#,Generics,Ienumerable,我有一个通用方法,我想把一个变量传递给它,如果这个变量是IEnumerable,那么把它的所有元素都设置为它的默认值。这就是我到目前为止所做的: public static T set_to_default<T>(T the_obj) { var the_enumerable = the_obj as IEnumerable; if (the_enumerable != null) { foreach (var element in the_e

我有一个通用方法,我想把一个变量传递给它,如果这个变量是IEnumerable,那么把它的所有元素都设置为它的默认值。这就是我到目前为止所做的:

public static T set_to_default<T>(T the_obj)
{
    var the_enumerable = the_obj as IEnumerable;
    if (the_enumerable != null)
    {
        foreach (var element in the_enumerable)
        {
            // I don't know what to put here
            // I want to set each element to its default value: default(T)
        }
        return the_obj;
    }
    else
    {
        return default(T);
    }
}
publicstatict设置为默认值(T对象)
{
var the_enumerable=作为IEnumerable的_obj;
if(_可枚举!=null)
{
foreach(可枚举项中的var元素)
{
//我不知道该在这里放什么
//我想将每个元素设置为其默认值:default(T)
}
返回_obj;
}
其他的
{
返回默认值(T);
}
}

我应该在foreach循环中放入什么?

在for循环中放入以下语句:

var default_val = Activator.CreateInstance(element.GetType());
这是设置为默认值的方式

这是一个完整的程序工作示例

class Program
{
    static void Main(string[] args)
    {
        var my_list = new List<int>() { 1, 2, 3 };
        var list2 = set_to_default<List<int>>(my_list);
        foreach (var elem in list2)
        {
            Console.WriteLine(elem);
        }

        Console.ReadKey();
    }

    public static T set_to_default<T>(T the_obj)
    {
        IEnumerable the_enumerable = the_obj as IEnumerable;
        if (the_enumerable != null)
        {
            Type type = the_enumerable.GetType().GetGenericArguments()[0];
            Type listType = typeof(List<>).MakeGenericType(new[] { type });
            IList list = (IList)Activator.CreateInstance(listType);

            var looper = the_enumerable.GetEnumerator();

            while (looper.MoveNext())
            {
                var current_obj = looper.Current;
                current_obj = Activator.CreateInstance(current_obj.GetType());
                list.Add(current_obj);


            }

            return (T)list;
        }
        else
        {
            return default(T);
        }
    }
}
类程序
{
静态void Main(字符串[]参数)
{
var my_list=new list(){1,2,3};
var list2=将_设置为默认值(我的_列表);
foreach(列表2中的变量元素)
{
控制台写入线(elem);
}
Console.ReadKey();
}
公共静态T设置为默认值(T对象)
{
IEnumerable可枚举=作为IEnumerable的对象;
if(_可枚举!=null)
{
类型类型=_enumerable.GetType().GetGenericArguments()[0];
Type listType=typeof(List).MakeGenericType(new[]{Type});
IList list=(IList)Activator.CreateInstance(listType);
var looper=可枚举的.GetEnumerator();
while(looper.MoveNext())
{
var current_obj=活套电流;
current_obj=Activator.CreateInstance(current_obj.GetType());
列表。添加(当前对象);
}
返回(T)列表;
}
其他的
{
返回默认值(T);
}
}
}

我建议使用列表而不是枚举,因为最后一个是不可变的。也就是说,一旦创建它们,就无法编辑它们


最后一件事……如果您想支持其他类型的IEnumerable,您可以使用C#'is'关键字来解决它。在这种情况下,您需要在运行时知道可枚举的底层类型。您可以使用C#“is”关键字来完成此操作

            if (the_enumerable is IList)
            {
                editableType = typeof(List<>).MakeGenericType(new[] { type });
            }
            else if(the_enumerable is ICollection)
            {
                ......
            }
if(可枚举项为IList)
{
editableType=typeof(List).MakeGenericType(新[]{type});
}
else if(_可枚举项为ICollection)
{
......
}

您应该只处理重载,这要简单得多(如果我正确理解您的问题的话)

注意,即使在这里,您也必须将值设置为函数的返回值。返回
void
并简单地执行
value=default(T)对于
int
等基本类型不起作用。这也是为什么这次我将它命名为
GetDefault
,而不是
SetToDefault

var myWhatever = 3.4;
myWhatever = myWhatever.GetDefault();

IEnumerable
不支持“设置”其值,因为它不一定表示具体的存储。你是说
i收集
?事实上,我认为
the_enumerable.Cast().Select(item=>default(T))
将执行您想要的操作,虽然这不是修改输入对象。如果将结果作为参数传递,该方法应该做什么?请澄清是否需要专门修改\u obj
的代码,或者是否可以基于
该\u obj
创建和返回新集合。在你的问题中,你三次提到“设置”ing“值”或“元素”加上你的存根代码
return
s
the_obj
,这听起来像是你想要更改
the_obj
的内容。如果没有这一澄清,您的问题目前还不清楚。@理想情况下,该方法会将_obj中的所有元素设置为默认值(T),而不创建新对象。好的,但是您知道,无法设置既不是an也不是an的元素,因为
IEnumerable
接口(就此而言,
IEnumerable
)根本不支持修改,是吗?你知道你是否会处理这样的输入对象吗?如果是的话,你必须返回一个新的
IEnumerable
。但是你如何处理
default\u val
?这是一个局部变量;你如何将该值赋给
可枚举的?同样,这也是一个问题使用
T
,而问题中的注释需要
default(T)
,这将是
null
,而不是引用类型的实例。我建议使用列表而不是枚举,因为最后一个列表是不可变的。也就是说,一旦创建它们,您就无法编辑它们。如果您不想得到“null”作为对象的默认值,您需要像下面的示例一样动态调用其构造函数Type=typeof(Addition);ConstructorInfo-ctor=Type.GetConstructor(new[]{typeof(int)});object-instance=ctor.Invoke(new-object[]{10});但这是可行的,因为您知道您的测试代码正在通过一个
列表
。如果您要做出这样的假设,您最好将它转换到
列表
,而不必费心处理
IEnumerable
。问题是如何处理
IEnumerable
输入。当您通过一个
IEnumerable
时,会发生什么呢t a
List
?在这种情况下,您需要在运行时知道可枚举文件的基本类型。如果(可枚举文件是IList){editableType=typeof(List)。MakeGenericType(new[]{type})},您可以使用C#'is'关键字来实现这一点
public static void Test()
{
    int myInt = 7;
    IEnumerable<int> myEnumberable = new List<int>() { 1, 4, 8, 9 };

    myInt = SetToDefault(myInt);
    myEnumberable = SetToDefault(myEnumberable);

    Console.WriteLine($"MyInt: {myInt}");
    Console.WriteLine($"MyEnumberable: {String.Join(", ", myEnumberable)}");
}
public static class Extensions {
    public static T GetDefault<T>(this T value) {
        return default(T);
    }
}
var myWhatever = 3.4;
myWhatever = myWhatever.GetDefault();