আমি জেনেরিক স্ট্যাটিক পদ্ধতি চাই যা "নুলযোগ্য" (কোনও রেফারেন্স টাইপ বা ন্যুয়েবলস) নিতে পারে এমন একটি সহজ মামলার জন্য এই ইস্যুটিতে ছড়িয়ে পড়েছি, যা সন্তোষজনক সমাধান ছাড়াই আমাকে এই প্রশ্নে নিয়ে এসেছিল। সুতরাং আমি আমার নিজের সমাধানটি নিয়ে এসেছি যা সমাধানের তুলনায় তুলনামূলক সহজতর ছিল ওপি'র বিবৃত প্রশ্নের তুলনায় কেবল দুটি ওভারলোডেড পদ্ধতি, যা একটি নেয় T
এবং সীমাবদ্ধতা রয়েছে where T : class
এবং অন্যটি গ্রহণ করে T?
এবং আছে where T : struct
।
আমি তখন বুঝতে পেরেছি, কনস্ট্রাক্টরকে ব্যক্তিগত (বা সুরক্ষিত) তৈরি করে এবং স্থির কারখানার পদ্ধতি ব্যবহার করে সংকলন করার সময় পরীক্ষা করতে সক্ষম এমন একটি সমাধান তৈরি করতেও এই সমস্যার সমাধান প্রয়োগ করা যেতে পারে:
//this class is to avoid having to supply generic type arguments
//to the static factory call (see CA1000)
public static class Foo
{
public static Foo<TFoo> Create<TFoo>(TFoo value)
where TFoo : class
{
return Foo<TFoo>.Create(value);
}
public static Foo<TFoo?> Create<TFoo>(TFoo? value)
where TFoo : struct
{
return Foo<TFoo?>.Create(value);
}
}
public class Foo<T>
{
private T item;
private Foo(T value)
{
item = value;
}
public bool IsNull()
{
return item == null;
}
internal static Foo<TFoo> Create<TFoo>(TFoo value)
where TFoo : class
{
return new Foo<TFoo>(value);
}
internal static Foo<TFoo?> Create<TFoo>(TFoo? value)
where TFoo : struct
{
return new Foo<TFoo?>(value);
}
}
এখন আমরা এটি এর মতো ব্যবহার করতে পারি:
var foo1 = new Foo<int>(1); //does not compile
var foo2 = Foo.Create(2); //does not compile
var foo3 = Foo.Create(""); //compiles
var foo4 = Foo.Create(new object()); //compiles
var foo5 = Foo.Create((int?)5); //compiles
আপনি যদি প্যারামিটারলেস কনস্ট্রাক্টর চান, আপনি ওভারলোডিংয়ের কুলুঙ্গিটি পাবেন না, তবে আপনি এখনও এর মতো কিছু করতে পারেন:
public static class Foo
{
public static Foo<TFoo> Create<TFoo>()
where TFoo : class
{
return Foo<TFoo>.Create<TFoo>();
}
public static Foo<TFoo?> CreateNullable<TFoo>()
where TFoo : struct
{
return Foo<TFoo?>.CreateNullable<TFoo>();
}
}
public class Foo<T>
{
private T item;
private Foo()
{
}
public bool IsNull()
{
return item == null;
}
internal static Foo<TFoo> Create<TFoo>()
where TFoo : class
{
return new Foo<TFoo>();
}
internal static Foo<TFoo?> CreateNullable<TFoo>()
where TFoo : struct
{
return new Foo<TFoo?>();
}
}
এবং এটি এর মতো ব্যবহার করুন:
var foo1 = new Foo<int>(); //does not compile
var foo2 = Foo.Create<int>(); //does not compile
var foo3 = Foo.Create<string>(); //compiles
var foo4 = Foo.Create<object>(); //compiles
var foo5 = Foo.CreateNullable<int>(); //compiles
এই সমাধানটির কয়েকটি অসুবিধা রয়েছে, একটি হ'ল আপনি অবজেক্টগুলি তৈরি করতে 'নতুন' ব্যবহার করতে পছন্দ করতে পারেন। আর একটি হ'ল আপনি Foo<T>
: এর মতো কোনও ধরণের সীমাবদ্ধতার জন্য জেনেরিক টাইপ আর্গুমেন্ট হিসাবে ব্যবহার করতে পারবেন না where TFoo: new()
। শেষ অবধি আপনার এখানে অতিরিক্ত কোডের দরকার হয় যা বিশেষত আপনার একাধিক ওভারলোডেড কনস্ট্রাক্টরের প্রয়োজন হলে বাড়বে।